java8新特性
创始人
2025-01-10 08:33:31
0次

目录

一. lambda

1. 为什么要有lambda

2.功能接口 

3. 使用lambda的条件

二. Stream流

1. 获取流

1.1 将集合转为流

1.2 将数组转为流

1.3 将相同数据类型的数据转为流

1.4 将文件里的内容转为流

2. 中间操作

3. 终端操作


一. lambda

lambda:本质上就是将函数当做参数进行传递

在java8之前,函数是不能直接当做参数传递的,因为java是面向对象的语言,一切皆对象,所以在java8之前都是将函数包装在对象中进行传递,java8之后我们可以利用lambda将函数当做参数传递,并且书写简单,这也是java提供的语法糖之一

1. 为什么要有lambda

我们之前要在一些方法中传递接口/抽象类的对象时,要先自己写一个接口/抽象类的实现类,并实现里面的抽象方法,才能将接口/抽象类的对象当做参数进行传递.如下

public class Demo1 {     public static void main(String[] args) {         ArrayList arrayList = new ArrayList<>();         arrayList.add("d");         arrayList.add("c");         arrayList.add("b");         arrayList.add("a");         arrayList.sort(new StringComparator1());         System.out.println();         System.out.println(arrayList);     } }
public class StringComparator1 implements Comparator {      @Override     public int compare(String o1, String o2) {         return o1.compareTo(o2);     } }

我们这样虽然可以,但是这个类只在这个方法中被使用,没有必要向外提供一个类,这个类显得很多余,所以我们有了第一种优化,将该类定义为内部类,这样外面就不知道我们这里还定义了一个类

public class Demo1 {     public static void main(String[] args) {         ArrayList arrayList = new ArrayList<>();         arrayList.add("d");         arrayList.add("c");         arrayList.add("b");         arrayList.add("a");         arrayList.sort(new StringComparator1());         System.out.println();         System.out.println(arrayList);     } }       static class StringComparator2 implements Comparator     {          @Override         public int compare(String o1, String o2) {             return o1.compareTo(o2);         }     }

 这样虽然有了一定的优化,但是我们在调用该方法时还是要创建一个类来实现里面的抽象方法,有没有办法不用我们自己定义一个类,就可以实现该方法呢,下面进行第二次优化

public class Demo1 {     public static void main(String[] args) {         ArrayList arrayList = new ArrayList<>();         arrayList.add("d");         arrayList.add("c");         arrayList.add("b");         arrayList.add("a");        //匿名内部类,为了减少类的创建        arrayList.sort(new Comparator() {             @Override             public int compare(String o1, String o2) {                 return o1.compareTo(o2);             }         });         System.out.println();         System.out.println(arrayList);     } }

这里我们直接创建了一个匿名内部类的对象,注意不是创建了接口/抽象类的对象,而是创建了一个类这个类没有名字,但是实现了该接口/抽象类中的方法,我们称之为匿名内部类,这样虽然简化了很多,也不用我们自己去创建类,但是其实上述代码,我们只关心的是compare这个方法的方法体,而不是该匿名内部类对象,所以为了再一次书写方便,简单,我们引入了lambda表达式

public class Demo1 {     public static void main(String[] args) {         ArrayList arrayList = new ArrayList<>();         arrayList.add("d");         arrayList.add("c");         arrayList.add("b");         arrayList.add("a");          //这是lambda表达式         arrayList.sort((a,b)->{             return a.compareTo(b);         });          System.out.println();         System.out.println(arrayList);     } }

2.功能接口 

功能接口:就是在定义接口时用@FunctionalInterface注解修饰的接口

作用:被@FunctionalInterface注解修饰的接口,在定义时,这个接口里只能有一个抽象方法,该注解会对接口进行检查,如果有两个或多个抽象方法编译器会报错

3. 使用lambda的条件

lambda的语法格式:

(参数列表)->{

方法体

}

参数列表是该接口有几个参数,这里就写几个形参,可以不写参数类型

方法体里面写重写该方法的内容

lambda的使用方法条件是该接口必须是功能接口(被@FunctionalInterface注解修饰的接口),即:该接口中只能有一个抽象方法.

一般在使用lambda时点到接口里面确定该接口是不是功能接口,如果是,再看有没有返回值以及有几个参数,这样就可以精确地使用lambda表达式了

为什么是功能接口才能使用lambda呢?

这是因为在使用lambda时只有函数体没有函数名,为了让编译器知道要调用哪个方法,我们在接口中就只定义一个抽象方法,这样编译器就知道调的肯定是这个方法,所以在使用lambda时必须确保该接口中只有一个抽象方法

二. Stream流

Stream流也是java为我们提供的语法糖,它用于将集合/数组转为流,利用流中提供的操作对集合/数组中的元素进行处理,处理完之后再转为集合/数组,也就是说Stream流类中是一种对集合/数组进行处理的操作,而具体的存储还是在集合/数组中

注意:

1.这里的Stream流不是IO流中的流

2.流的操作分为获取流,中间操作和终端操作

1. 获取流

1.1 将集合转为流

 Stream stream = arrayList.stream();//把集合转为流

利用集合中的stream()方法就可以实现将集合转为流

1.2 将数组转为流

Integer[] array = new Integer[]{1,2,3,4}; Stream stream1 = Arrays.stream(array);//把数组转为流

利用Arrays类中的stream()方法就可以将数组转为流

1.3 将相同数据类型的数据转为流

  Stream.of(1,2,3,4,5);//将同一类型的数据转为流(可变参数)

利用Stream类中的静态方法of(),该方法可以传入相同类型的数据,并且传入的形参是可变参数,即数据个数是任意的

1.4 将文件里的内容转为流

BufferedReader reader=new BufferedReader(new FileReader("stream.txt")); Stream lineStream = reader.lines();

利用BufferedReader中的lines()方法将读到的一行内容转为流

2. 中间操作

中间操作就是将集合/数组转为流后,对数据进行的处理操作

filter(Predicate predicate)对满足条件的数据进行过滤,满足留在流中,不满足去掉
sorted(Comparator)对流中的元素进行排序,默认升序
distinct()去除流中的重复元素
limit(n)获取流中的n个元素
skip(n)跳过n个元素,配合limit(n)可实现分页
Integer[] array = new Integer[]{1,2,3,4,2,5}; Arrays.stream(array)    .skip(2)    .limit(2)    .sorted()    .distinct()    .forEach((e)->{       System.out.print(e+" ");                 });

3. 终端操作

终端操作就是将流转为集合/数组,或者是获得一个处理后的结果

forEach()对流中的元素进行遍历
toArray()将流中的元素倒入一个数组
Optional Min(Comparator )返回流中元素最小值
Optional Max(Comparator )返回流中元素最大值
long count()返回流中元素的总个数
Optional Reduce(BinaryOperator)返回流中所有元素的和
boolean anyMatch(Predicate)只要流中有一个元素满足条件返回true,否则返回false
boolean allMatch(Predicate)当流中所有元素满足条件返回true,否则返回false
findFirst()返回流中第一个元素
map将对象中的某个值放到一个新的集合/数组中
collect将流转为list,set,map集合

相关内容

热门资讯

实测交流透视挂!宝玛大厅ai智... 实测交流透视挂!宝玛大厅ai智能透视挂教程,宝玛大厅破解软件经验(本来有挂辅助)1、每一步都需要思考...
总算了解辅助器!朱雀吴江三缺一... 总算了解辅助器!朱雀吴江三缺一ai智能透视辅助挂技巧,朱雀吴江三缺一好像是有挂(有辅助挂细节)朱雀吴...
今日公布透视!九五至尊大厅ai... 今日公布透视!九五至尊大厅ai智能透视插件,九五至尊大厅有没有透视挂窍门(切实有挂技术)1、在九五至...
玩家必看科普开挂!聚闲麻将ai... 玩家必看科普开挂!聚闲麻将ai智能透视辅助挂软件,聚闲麻将总是真的有挂(有辅助挂方式)聚闲麻将能透视...
据报道开挂!旅游娱乐ai智能开... 据报道开挂!旅游娱乐ai智能开挂工具,旅游娱乐辅助工具演示(一直有挂教学)1、全新机制【旅游娱乐ai...
一分钟揭秘开挂!决胜朋来麻将a... 一分钟揭秘开挂!决胜朋来麻将ai智能透视辅助挂教程,决胜朋来麻将真是真的是有挂(有辅助挂总结)1、首...
如何分辨真伪透视!红牛ai智能... 如何分辨真伪透视!红牛ai智能透视攻略,红牛是不是有挂经验(真是有挂技术)1、操作简单,无需红牛手机...
2分钟细说辅助器!江湖大庆麻将... 2分钟细说辅助器!江湖大庆麻将ai智能透视辅助挂攻略,江湖大庆麻将竟然是真的有挂(有辅助挂头条)1、...
总算清楚透视挂!老夫子厅ai智... 总算清楚透视挂!老夫子厅ai智能透视挂技巧,老夫子厅怎么开挂课程(好像发现有挂)老夫子厅破解侠是真的...
解密关于辅助!菜鸟麻将ai智能... 解密关于辅助!菜鸟麻将ai智能透视辅助挂脚本,菜鸟麻将总是存在有挂(有辅助挂存在)1、用户打开应用后...