java8 list 行转列_Java14 都来了,你还不会用 Java8吗?

26657d8d85c6129788f838fbd407333e.png

Java 8 于2014年3月18日发布,并且成为主流的 Java,如今,虽然 Java 14 都已经发布了,但是 开发者和公司选择的版本依旧是经久不衰的 Java 8 版本,如果你还不了解这些新特性,是时候学习一下了。

Java 8 更新的一些重要功能一览

  • Iterable 接口中的 forEach() 方法
  • 接口中的默认方法和静态方法
  • 功能接口和 Lambda 表达式
  • 用于集合上批量数据操作的 Java Stream API
  • Java 时间 API
  • 集合 API 的改进
  • 并发 API 改进
  • Java IO改进
  • 其他核心 API 改进

下面来简要了解一下这些Java 8功能。我将提供一些代码片段以更好地理解,因此,如果要在Java 8中运行程序,则必须按照以下步骤设置Java 8环境。

下载并安装JDK8。像其他Java版本一样,安装也很简单,运行下面的示例,必须要安装 JDK 环境。

下载最新的 IDEA 开发环境,这里我不推荐使用 Eclipse ,但是如果你有使用 Eclipse 习惯,那我在这里推荐你可以尝试 IDEA,因为它真的太棒啦~

Iterable 接口中的 forEach()方法

在 Java 8 以前,每当需要遍历 Collection 时,就需要创建一个 Iterator 来进行迭代 Collection 对象,然后针对 Collection 中 的每个元素将业务逻辑循环在一起。如果迭代器使用不正确,可能会抛出 ConcurrentModificationException。

Java 8 在接口中引入了forEach方法,java.lang.Iterable因此在编写代码时,我们仅关注业务逻辑。forEach方法将java.util.function.Consumer对象作为参数,因此有助于将我们的业务逻辑放在一个可以重用的单独位置。让我们通过简单的示例查看forEach用法。

package com.journaldev.java8.foreach;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.function.Consumer;import java.lang.Integer;public class Java8ForEachExample {    public static void main(String[] args) {        //creating sample Collection        List myList = new ArrayList();        for(int i=0; i<10; i++) myList.add(i);        //traversing using Iterator        Iterator it = myList.iterator();        while(it.hasNext()){            Integer i = it.next();            System.out.println("Iterator Value::"+i);        }        //traversing through forEach method of Iterable with anonymous class        myList.forEach(new Consumer() {            public void accept(Integer t) {                System.out.println("forEach anonymous class Value::"+t);            }        });        //traversing with Consumer interface implementation        MyConsumer action = new MyConsumer();        myList.forEach(action);    }}//Consumer implementation that can be reusedclass MyConsumer implements Consumer{    public void accept(Integer t) {        System.out.println("Consumer impl Value::"+t);    }}

代码的行数可能会增加,但是forEach方法有助于将迭代逻辑和业务逻辑放在不同的位置,从而使关注点和代码更清晰地分离。

接口中的默认方法和静态方法

如果仔细阅读forEach方法的详细信息,会注意到它是在Iterable接口中定义的,但我们知道接口不能具有方法主体。从Java 8开始,接口已增强为具有实现的方法。我们可以使用default和static关键字来创建带有方法实现的接口。Iterable接口中的forEach方法实现为:

default void forEach(Consumer super T> action) {    Objects.requireNonNull(action);    for (T t : this) {        action.accept(t);    }}

我们知道Java不会在Class中提供多重继承,因为它会导致Diamond问题。由于接口现在类似于抽象类,因此现在如何使用接口处理它。解决方案是在这种情况下编译器将引发异常,我们将不得不在实现接口的类中提供实现逻辑。

package com.journaldev.java8.defaultmethod;@FunctionalInterfacepublic interface Interface1 {    void method1(String str);    default void log(String str){        System.out.println("I1 logging::"+str);    }    static void print(String str){        System.out.println("Printing "+str);    }    //trying to override Object method gives compile-time error as    //"A default method cannot override a method from java.lang.Object"//    default String toString(){//        return "i1";//    }}
package com.journaldev.java8.defaultmethod;@FunctionalInterfacepublic interface Interface2 {    void method2();    default void log(String str){        System.out.println("I2 logging::"+str);    }}

注意,两个接口都有一个带有实现逻辑的通用方法log()。

package com.journaldev.java8.defaultmethod;public class MyClass implements Interface1, Interface2 {    @Override    public void method2() {    }    @Override    public void method1(String str) {    }    //MyClass won't compile without having it's own log() implementation    @Override    public void log(String str){        System.out.println("MyClass logging::"+str);        Interface1.print("abc");    }}

如你所见, Interface1 具有在 MyClass.log() 方法实现中使用的静态方法实现。Java 8 在 Collection API 中大量使用默认和静态方法,并且添加了默认方法,以便使 JDK 8 之前的代码保持向后兼容。

如果层次结构中的任何类都具有具有相同的方法,则默认方法将变得无关紧要。由于任何实现接口的类都已经具有 Object 作为超类,因此如果接口中具有 equals(),hashCode() 默认方法,它将变得无关紧要。这就是为什么为了更清楚起见,不允许接口具有Object默认方法。

有关Java 8接口特性的完整详细信息,请阅读 Java 8接口更改。

功能接口和Lambda表达式

如果你注意到上述接口代码,则会注意到 @FunctionalInterface 注解。该功能接口是Java 8 中引入的新概念。具有一种抽象方法的接口就变成了功能接口。我们不需要使用 @FunctionalInterface 注解将接口标记为Functional Interface。@FunctionalInterface 注解是一种避免在功能接口中意外添加抽象方法的工具。您可以将其视为 @Override 批注,并且是使用它的最佳实践。java.lang.Runnable 使用单个抽象方法 run() 是功能接口的一个很好的例子。

功能接口的主要优点之一是可以使用 lambda 表达式实例化它们。在 Java 8 之前,可以用匿名类实例化一个接口,但是代码看起来很庞大。

Runnable r = new Runnable(){    @Override    public void run() {            System.out.println("My Runnable");    }};

由于功能接口只有一种方法,因此 lambda 表达式可以轻松提供该方法的实现。只需要提供方法参数和业务逻辑。例如,可以使用 lambda 表达式编写上面的实现:

Runnable r1 = () -> {            System.out.println("My Runnable");        };

如果方法实现中只有一条语句,那么我们也不需要花括号。例如,上面的Interface1匿名类可以使用lambda实例化,如下所示:

Interface1 i1 = (s) -> System.out.println(s);i1.method1("abc");

因此,lambda 表达式是轻松创建功能接口的匿名类的一种方法。使用 lambda 表达式对于代码运行没有任何的影响,因此要谨慎谨慎使用它,因为我们并不介意编写一些额外的代码行。

新包装 java.util.function 添加了带有功能接口束的,以提供 lambda 表达式和方法引用的目标类型。Lambda 表达式是一个非常复杂的话题,后续我会编写一篇文章专门针对 lambda 表达式。

您可以在 Java 8 Lambda Expressions Tutorial 中阅读完整的教程。

用于集合上批量数据操作的Java Stream API

java.util.stream 是Java 8中添加的一个新内容,以对该集合执行类似过滤/映射/遍历的操作。Stream API 将允许顺序执行和并行执行。这对我来说是非常好用的一个功能,因为我经常处理 Collections,而且通常使用很多的数据进行过滤数据,遍历数据,stream 就完美的解决了这个问题。

Collection 接口已使用 stream() 和 parallelStream() 默认方法进行了扩展,以获取用于顺序执行和并行执行的 Stream ,用一个简单的例子看看它们的用法。

package com.journaldev.java8.stream;import java.util.ArrayList;import java.util.List;import java.util.stream.Stream;public class StreamExample {    public static void main(String[] args) {        List myList = new ArrayList<>();        for(int i=0; i<100; i++) myList.add(i);        //sequential stream        Stream sequentialStream = myList.stream();        //parallel stream        Stream parallelStream = myList.parallelStream();        //using lambda with Stream API, filter example        Stream highNums = parallelStream.filter(p -> p > 90);        //using lambda in forEach        highNums.forEach(p -> System.out.println("High Nums parallel="+p));        Stream highNumsSeq = sequentialStream.filter(p -> p > 90);        highNumsSeq.forEach(p -> System.out.println("High Nums sequential="+p));    }}

如果你运行示例代码,将获得如下输出:

High Nums parallel=91High Nums parallel=96High Nums parallel=93High Nums parallel=98High Nums parallel=94High Nums parallel=95High Nums parallel=97High Nums parallel=92High Nums parallel=99High Nums sequential=91High Nums sequential=92High Nums sequential=93High Nums sequential=94High Nums sequential=95High Nums sequential=96High Nums sequential=97High Nums sequential=98High Nums sequential=99

请注意,并行处理的时候。值不按顺序排列,因此在处理庞大的集合时,并行处理将非常有帮助。

这篇文章无法涵盖有关Stream API的所有内容,您可以在 Java 8 Stream API Example Tutorial 中阅读有关Stream API的所有内容。

Java 8 时间API

在之前的 Java 中使用日期,时间和时区一直很困难。Java 中没有用于日期和时间的标准方法或 API。Java 8 有一个不错的附加功能是 java.time 软件包,它简化了 Java 中使用时间的过程。

仅查看 Java Time API 软件包,就可以感觉到它非常易于使用。它具有一些子包 java.time.format,这些子包提供用于打印和解析日期和时间的类,还有java.time.zone 提供对时区及其规则的支持。

新的 Time API 在整月的几个月和一周中的几天中都使用了枚举而不是整数常量。常用的类之一是 DateTimeFormatter 将 DateTime 对象转换为字符串。

有关完整的教程,请转到 Java日期时间API示例教程。

集合API的改进

在上面的介绍已经看到了 forEach() 方法和用于集合的 Stream API。

Collection API 中添加的一些新方法是:

IteratorforEachRemaining(Consumer action) 在所有元素都已处理完毕或该动作引发异常之前,对其余每个元素执行给定操作的默认方法。

CollectionremoveIf(Predicate filter) 删除此集合中所有满足给定谓词的元素的默认方法。

Collection spliterator() 该方法返回Spliterator实例,该实例可用于顺序或并行遍历元素。地图replaceAll(),compute(),merge()方法。

另外还有一些具有 hash 冲突 的HashMap 类的性能改进

并发API改进

一些重要的并发API增强功能包括:

ConcurrentHashMap compute(),forEach(),forEachEntry(),forEachKey(),forEachValue(),merge(),reduce()和search()方法。CompletableFuture 可以明确完成(设置其值和状态)。Executors newWorkStealingPool() 使用所有可用处理器作为目标并行度级别创建窃取线程池的方法。

Java IO改进

我知道的一些IO改进:

Files.list(Path dir) 返回一个延迟加载的 Stream,其元素是目录中的文件夹和文件列表。

Files.lines(Path path) 返回一个读取指定文件所有行的文件流。

Files.find() 返回一个根据指定目录搜索指定文件的文件列表流。

BufferedReader.lines() 返回一个Stream,其元素是从此 BufferedReader 中读取的行。

其他核心API改进

一些杂项API改进在某些特殊情况可能会派上用场:

  • ThreadLocal 静态方法可以使用 withInitial 方法创建实例。
  • 比较器接口已扩展了许多默认和静态方法,用于自然排序,反向排序等。
  • Integer,Long 和 Double 包装器类中增加了 min(),max() 和 sum() 方法。
  • Boolean 类中的 logicalAnd() ,logicalOr() 和 logicalXor() 方法。
  • ZipFile.stream() 方法获取 ZIP 文件条目上的有序Stream,并以压缩时的顺序出现在 Stream 中。
  • Math 类中增加了几种实用方法。
  • jjs 添加命令以调用 Nashorn Engine。
  • jdeps 添加命令以分析类文件
  • JDBC-ODBC 桥已被删除。
  • PermGen 内存空间已被删除

码字不易,如果能帮到你,请点点关注~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/245109.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql主键用完了怎么办_MySQL 自增 ID 用完了怎么办?

MySQL 自增 ID 用完了怎么办&#xff1f;在MySQL中有很多类型的自增ID&#xff0c;每个自增ID都设置了初始值&#xff0c;然后按照一定的步长增加&#xff0c;只要定义了字节长度&#xff0c;那么就会有上限&#xff0c;如果达到上限再次添加&#xff0c;则会报主键冲突错误&am…

python字典统计_python字典计数

广告关闭 腾讯云11.11云上盛惠 &#xff0c;精选热门产品助力上云&#xff0c;云服务器首年88元起&#xff0c;买的越多返的越多&#xff0c;最高返5000元&#xff01;字典?thcollections.counter 计数器? image.png找不到键的时候会调用miss方法如果键不是字符串&#xff0c…

java相册_精致小巧的java相册制作方法

本文实例为大家分享了java相册制作方法&#xff0c;供大家参考&#xff0c;具体内容如下注&#xff1a;1)html上的图片是静态指定的。当更新了新的图片时必须手工更新。所以使用Servlet读取本地images中的所有图片&#xff0c;动态显示给用户。2)如果存在中文名的图片&#xff…

利用python画分形图_使用 Python 绘制 Mandelbrot 分形图

以前收集的关于Mandelbrot分形图的Python脚本&#xff0c;Mandelbrot集合的图像因它洛可可式繁复卷曲华丽的风格而受到大众的欣赏和赞叹&#xff0c;与其他分形图案一起&#xff0c;是许多艺术家和设计师的灵感来源。 是由于今天个人电脑计算能力的强大&#xff0c;才有可能让我…

java sound api_Java Sound API

Java Sound API是javaSE平台提供底层的(low-level)处理声音接口。例外&#xff0c;java也提供了简单的实用的高层媒体接口(higher-level) &#xff0d; JMF(Java Media Framework)。Java Sound API 将需要处理的数字音频分为&#xff1a;simpled-audio和midi,分别提供Package来…

java实现的小程序_Java实现 微信小程序 + 消息推送

实现效果&#xff1a;下面要显示五个字段接下来&#xff0c;参照官方文档&#xff0c;一步步实现&#xff1a;一、官方给出请求示例、返回示例二、根据上面编写实体类(1)请求参数Datapublic class SendTemplateReq {/*** 接收者(用户)的 openid*/private String touser;/*** 所…

vb excel 整行删除_Excel中常用的批量处理都不掌握,那就真的Out了

针对一些有规律&#xff0c;能批量处理的数据&#xff0c;必须采用批量处理的方法&#xff0c;否则对于工作效率就会有很大的影响。今天我们来学习的内容是Excel中的6个批量处理技巧。一、Excel批量技巧&#xff1a;批量求和。目的&#xff1a;按照“季度”和“产品”两个维度计…

exe编辑器_【小功能】Unreal Editor中调用exe

后续文章更新移步→微信公众号“虚幻社区”&#xff08;mantra-xhsq&#xff09;&#xff0c;您的支持是我创作的动力。在程序界混&#xff0c;哪能碰上不改需求的策划 --Mantra最近遇到了一个奇葩的需求&#xff0c;在Unreal Editor的Toolbar中添加一个快捷键&#xff0c;可以…

html select选择事件_按键精灵的Html系列命令实战讲解

金猪脚本(原飞猪脚本)以按键精灵教学为主,涉及UiBot&#xff0c;Python,Lua等脚本编程语言,教学包括全自动办公脚本,游戏辅助脚本,引流脚本,网页脚本,安卓脚本,IOS脚本,注册脚本,点赞脚本,阅读脚本以及网赚脚本等各个领域。想学习按键精灵的朋友可以添加金猪脚本粉丝交流群:554…

java 验证码_java学习之web基础(6):使用Response的输出流在页面输出验证码

package 输出并且我们可以写一个简单的网页&#xff0c;来实现点击更新验证码<!DOCTYPE html>

java socket编程实现聊天程序_java Socket编程 聊天程序 服务器端和客户端

[java]代码库package com.gufengxiachen.sthreadchatapp;/*** author GUXIA*/import java.io.BufferedReader;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;imp…

电商前台模板中文html5_跨境电商平台上产品如何上传?虾皮新版批量上传工具使用指南分享...

大家好&#xff0c;这里是天师跨境&#xff0c;今天来为电商新人们解答一下关于如何在跨境电商平台上上传产品的疑惑&#xff0c;顺便介绍一下虾皮跨境平台的新版批量上传工具是如何使用的。在跨境电商平台上开店的新手们在入驻成功后&#xff0c;一般最先面临的问题就是上传产…

移动端 关闭浏览器事件_前端开发中什么是移动端点透事件?

点透事件&#xff1a;是指两个元素其中一个元素具有默认的点击事件&#xff0c;当我们让不具有点击事件的元素隐藏起来&#xff0c;会触发另一个元素的点击事件&#xff0c;这种行为被称之为点透事件。如下图所示&#xff1a;当我们给div元素添加touchstart事件让div元素隐藏起…

清除浏览器缓存之后为什么还是显示旧的html页面_Web缓存控制策略详解

管理Web缓存的最常用和最有效的方法之一是通过Cache-Control HTTP标头&#xff0c;由于此标头适用于Web页面的缓存&#xff0c;这意味着我们页面上的所有内容都可以具有非常精细化的缓存策略。通过各种自定义策略&#xff0c;我们控制的策略就可以变得非常复杂和强大。Cache-Co…

java jtextfield 事件_JAVA JTextField事件处理

初学JAVA&#xff0c;笔记&#xff1a;package windows;import javax.swing.*;import java.awt.*;import java.awt.event.*;class WindowFlow extends JFrame implements ActionListener{private static final long serialVersionUID 1L;JTextField text1,text2;WindowFlow(St…

js封装函数_JavaScript基础-如何封装函数来改变元素的位置

点击右上方红色按钮关注“小郑搞码事”&#xff0c;每天都能学到知识&#xff0c;搞懂一个问题&#xff01;大家好&#xff01;我是/小郑搞码事/的小郑今天给大家分享JavaScript的基础知识-改变元素的位置。没错&#xff0c;用JS实现过动画的同学都应该了解一点&#xff0c;简单…

java程序设计与实践教程 王薇 doc_Java程序设计与实践教程 王薇主编 答案

Java程序设计与实践教程 王薇 主编 董迎红 副主编 课后习题 答案第1章 JAVA简介一、判断题1.√ 2.√ 3. 4. 5. 6.√ 7.√ 8.√ 9. 10.二、填空题1.Application Applet 2. 类(字节码文件、目标文件) .class3.对象 4. 主 5. J2SE J2EE J2ME三、选择题1.B 2. D 3.B 4.B 5. A四、简…

maya藤蔓插件_Maya特效制作之植物生长动画制作教程(二)之多条藤蔓动画制作...

四、制作多条蔓藤植物下面我们要让很多植物在这个“崖壁”上生长出来&#xff0c;也就是要重复很多次前面的工作&#xff0c;当然可以这样一步一步地做&#xff0c;在“崖壁”面片上手动画很多的线&#xff0c;但下面尝试一种新的方法来制作&#xff0c;让粒子在“崖壁”面片Pl…

mysql数据库导入导出_MySQL数据库导入导出详解

MySQL数据库的导入&#xff0c;有两种方法&#xff1a;1) 先导出数据库SQL脚本&#xff0c;再导入&#xff1b;2) 直接拷贝数据库目录和文件。在不同操作系统或MySQL版本情况1. 概述MySQL数据库的导入&#xff0c;有两种方法&#xff1a;1) 先导出数据库SQL脚本&#xff0c;再导…

代码统计工具有哪几种_跟我学“Linux”小程序Web版开发(四):引入统计及Crash收集...

在完成了产品的基础开发以后&#xff0c;接下来需要进行一些周边的工作&#xff0c;这些周边工具将会帮助下一步优化产品。在完成了产品的基础开发以后&#xff0c;接下来需要进行一些周边的工作&#xff0c;这些周边工具将会帮助下一步优化产品。为什么要加应用统计和 Crash 收…