提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
JAVA基础之方法引用、Stream
前言
今天学习了方法引用和Stream流。
一、方法引用
方法引用的基础就是Lambda表达式的理解和对函数式接口的清晰认识。
其本质是对Lambda表达式的简化。使用方法引用和Lambda表达式都是一样的。
简化的前提 :lambda表达式的lambda体{}中的实现,就是通过调用另外一个方法实现的,这种情况下,就可以进一步分析是否可以通过方法引用来简化lambda表达式
当满足不同条件时,使用的方式会有所不同。
当满足下列情况时,即当lambda表达式的参数列表与返回值直接对应匹配内部lambda体中所引用方法的参数列表与返回值的时候 -->对象::成员方法名 | 类名::静态方法名
示例代码如下:
public static void main(String[] args) {
//对象.方法
List<Integer> list = List.of(12,54,78,90,10);
list.forEach(s-> System.out.println(s));
list.forEach(System.out::println);
//类.方法
BiFunction<Integer,Integer,Integer> biFunction = (x, y) -> Math.max(x,y);
BiFunction<Integer, Integer, Integer> biFunction1 = Math::max;
System.out.println(biFunction1.apply(4, 3));
当满足下列情况时,当内部所引用方法的返回值直接匹配对应lambda表达式的返回值,lambda表达式的参数列表第一个参数匹配调用内部所引用方法的对象存在,lambda表达式的第二个参数开始直接匹配对应内部所引用方法的参数列表 -->类名::成员方法名
简而言之就是第一个参数是引用方法的对象,且之后所有参数是引用方法的参数列表
示例代码如下:
//类.方法
BiPredicate<String,String> biPredicate = (x,y)->x.equals(y);
BiPredicate<String,String> biPredicate1 = String::equals;
System.out.println(biPredicate1.test("abc","abcd"));
二、Stream流
1、什么是Stram流
Stream流就是将数据转化成流,操作像流一样操作丝滑和便捷。举一个简单的例子,帮助理解。
假设有一个农民正在收割他的庄稼,他需要从田地中选择出成熟的水果,并将其放入篮子中。这个过程可以类比为使用Stream流对一个集合进行操作。首先,农民将田地中的水果看做一个集合,他需要将集合中的水果按照成熟程度进行筛选,并将筛选出来的水果放入篮子中。如果他一起筛选肯定需要多个人去看,一个人的去筛选就按照链式去操作,每个筛选的结果传给下一论筛选的开始,最后将满足条件的水果收集起来。
Stream流的特点:
1、Stream流是一种惰性求值的方式,只有在需要结果时才会进行计算。2、 Stream流的操作可以形成一个流水线,每个操作都会返回一个新的Stream,可以链式调用多个操作。
3、 Stream流的操作可以进行并行处理,提高处理效率。
4、Stream流对集合和数组进行操作,不会修改原始数据,而是返回一个新的Stream或其他数据类型。
注意:
- Stream只有遇到终止操作(例如:Foreach())才能将流转化为数据
- Stream在链式调用方法的时候,传递的一定是流,如果遇到终止操作就就一定结束流的中间操作了
2、Stream的基本操作
Stream流的操作分为三步:
- 构建Stream流
- 中间操作(筛选)
- 终止操作(输出数据)
示例代码如下:
Stream<Double> stream2 = Stream.of(20.1,23.3,33.3);
stream2.forEach(System.out::println);
List<Employee> list = new ArrayList<>();//构建流
list.add(new Employee(01,"迪迦", 12000));
list.add(new Employee(02,"盖亚", 13000));
list.add(new Employee(03,"戴拿", 14000));
list.add(new Employee(03,"戴拿", 14000));
list.add(new Employee(05,"华哥", 9000));
System.out.println(list.stream()
.filter(x -> x.getPrice() > 10)//中间操作 过滤器:将price大于10放入流中
.limit(2)//中间操作 将流中的前两天数据放入流中
.skip(1)//中间操作 只保留流中的一条数据
.sorted((x, y) -> Integer.compare(x.getPrice(), y.getPrice()))//中间操作 排序
.count());//终止操作 输出流中的数据
输出结果如下:
筛选操作有很多,不在这过多赘述,下次再分享。
3、Stream的映射
Stream的映射有两种:Map映射、flatMap映射
Map映射操作可以理解为一对一的映射,即将集合中的每个元素按照某种规则映射为另一个元素。
flatMap映射操作可以对集合中的每个元素返回一个Stream流,然后将这些Stream流合并成一个新的Stream。
示例代码如下:
Map映射
List<String> list = Arrays.asList("apple", "banana", "orange");
List<String> upperList = list.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(upperList);
输出结果如下:
示例代码如下:
FlatMap映射:
List<List<Integer>> list = Arrays.asList(
Arrays.asList(1, 2),
Arrays.asList(3, 4),
Arrays.asList(5, 6)
);
List<Integer> flatList = list.stream()
.flatMap(Collection::stream)
.collect(Collectors.toList());
System.out.println(flatList);
输出结果如下:
4、Stream的终止操作
Stream的操作有很多下列个是常见的:
1、forEach:对Stream中的每个元素执行给定的操作。
示例代码如下:
Stream<Double> stream2 = Stream.of(20.1, 23.3, 33.3);
stream2.forEach(System.out::println);
输出结果如下:
2、reduce:将Stream中的元素归约为一个值。
示例代码如下:
//规约:reduce
System.out.println(list.stream()
.distinct()
.map(e -> e.getPrice())
.reduce((x, y) -> x + y));
//有起始值的规约
System.out.println(list.stream()
.distinct()
.map(e -> e.getPrice())
.reduce(100,(x, y) -> x + y));
输出结果如下:
3、collect:将Stream中的元素收集到一个集合中。
示例代码如下:
//收集collect toList
List<Employee> list1 = list.stream()
.filter(x->x.getPrice()>10000&&x.getPrice()<15000)
.collect(Collectors.toList());
System.out.println(list1);
//收集collect toSet
Set<Employee> set = list.stream()
.filter(x->x.getPrice()>10000&&x.getPrice()<15000)
.collect(Collectors.toSet());
System.out.println(set);
// 收集collect toMap
Map<Integer,String> m = list.stream()
.distinct()
.collect(Collectors.toMap(Employee::getId,Employee::getName));
System.out.println(m);
输出结果如下:
4、count:返回Stream中元素的数量。
示例代码如下:
List<Employee> list = new ArrayList<>();
list.add(new Employee(01, "迪迦", 12000));
list.add(new Employee(02, "盖亚", 13000));
list.add(new Employee(03, "戴拿", 14000));
list.add(new Employee(03, "戴拿", 14000));
list.add(new Employee(05, "华哥", 9000));
//count
System.out.println(list.stream()
.filter(x -> x.getPrice() > 10)
.count());
输出结果如下:
5、min/max:返回Stream中的最小/最大元素。
示例代码如下:
System.out.println(list.stream()
.filter(x -> x.getPrice() > 10000)
.max((x, y) -> Integer.compare(x.getPrice(), y.getPrice())));
输出结果如下:
总结
主要是对Stream流操作的认识和熟练掌握,在面对Stream操作时能清晰的知道结构以及用法。明天加油!!