多用Java stream

Stream(java.util.Stream)可是java8的东西了,java8是14年3月份出的正式版,现在都2021,马上就2022了,对于java8来说是新特性,可是对于实际时间来说,这能算是老掉牙的东西了,那些“新特性”早已经不能说“新”了。
虽然说使用Stream实现的功能,都能使用其它方法来实现,但是同样是实现某个功能,使用Stream却能大大减少代码冗余,省时又省力,不仅要了解,而且得多用,随着实践、工作的时间推移,代码的逼格也应该要提上去,才能在业务开发中做一个高效的CRUD Boy。
Stream搭配Lambda表达式,就可以把集合(Collection)玩弄于鼓掌之中,并且特别简单。Stream翻译成中文叫做流,Stream将集合看成是一种流,在流中,Stream API提供了很多的方法可以对流中的元素进行各种操作:排序、筛选、归集、聚合等等。
Java8 API官网文档:https://docs.oracle.com/javase/8/docs/api/
Java8 API国内中文文档:https://www.matools.com/api/java8
看文档特别重要!
找到java.util.stream包,里面的Stream接口下面总共也就39个方法。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k9cJSbe3-1681629344261)(/upload/2021/12/image-cff09e27a0ca4894b70a260d4390ca8d.png)]
流的操作基于三个要素:数据源、中间操作、终端操作
数据源就是你需要操作的集合对象,可以是数组、list、set等Java容器或I/O channel;
中间操作:中间操作就是中间的操作,它的目的是打开流,而不会消耗流,可以连续有很多个流操作,它就像是一个流水线,对流元素做一些数据映射、过滤,然后会返回一个新的流,交给下一个操作使用,这些操作都是惰性的(惰性就是说,这些中间操作的方法一开始并不会真的执行,在终端操作开始之后才能真正地开始执行中间操作),终端操作是什么?
终端操作:是最终返回的结果,它会消耗流,一个流只能有一个终端操作,当这个操作执行之后,流就会被用掉(消费)了,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成,所以终端操作一定是在整个流操作的最后面的。
比如:

List<String> dataStrList = Arrays.asList("aa","aa","ab","bc");
Set<String> set = dataStrList .stream().filter(str -> str.contains("a")).collect(Collectors.toSet());

dataStrList 是数据源,filter是中间操作方法(不会消耗流),返回一个过滤后的流,collect是终端操作(消耗流),这里面是把所有元素收集到一个set,消除重复元素。
中间操作和终端操作的方法:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bYafZfSR-1681629344262)(/upload/2021/11/1638278484(1)]-0d23dba63e614a0589261975157fb185.jpg)
stream中的元素是以Optional对象(一个可以为空的容器,是java8中为解决NullPointerException而出现的类)存在的,流还可以分为顺序流(stream)和并行流(parallelStream),并行流就等于是将一个顺序流切割成若干个小顺序流,最后合并结果。
stream的一些特性:
(1)stream不存储数据,只按照特定的规则对数据进行计算,一般会输出结果;
(2)stream不会改变数据源,通常情况下会产生一个新的集合或一个值;
(3)stream具有延迟执行特性,只有调用终端操作时,中间操作才会执行。
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

记录一些常用的Stream的操作方法

1、filter(筛选)

将流中符合一定条件的元素找出来,组成一个新的流。

//筛选大于10的元素,并打印出来
List<Integer> list = Arrays.asList(1, 2, 13, 66, 53, 6, 17);
	      list.stream.filter(x -> x > 10).forEach(System.out::println);

System.out::println的::是一个Lambda表达式,是方法引用的一种写法,有很多种引用情景,在这里是对象的实例方法引用语法 instancename::methodname。
其他还有:
静态方法引用(static method)语法:classname::methodname 例如:User::getName
对象的超类方法引用语法: super::methodname
类构造器引用语法: classname::new 例如:ArrayList::new
数组构造器引用语法: typename[]::new 例如: String[]:new。

2、forEach、find、match(匹配、遍历)
List<Integer> list = Arrays.asList(11, 22, 33, 23, 18, 15, 2);
//遍历输出符合条件的元素
List.stream().filter(x -> x > 20).forEach(System.out::println);
//匹配第一个符合条件的元素
Optional<Integer> findFirst = list.stream().filter(x -> x > 20).findFirst();
Integer findFirst1 = Integer.valueOf(list.stream().filter(x -> x > 20).findFirst().toString());
//匹配任意一个符合条件的元素(在并行流中才有此方法)
Optional<Integer> findAny = List.paralllelStream().filter(x -> x > 20).findAny();
//判断流中是否所有元素都匹配特定值
boolean allMatch= list.stream().allMatch(x -> x > 20);
//判断是否存在特定元素,返回一个boolean值
boolean anyMatch = list.stream().anyMatch(x -> x > 20);
//noneMatch():如果流中没有元素匹配提供的谓词或流是空的返回true,否则 false
3.count、max、min(聚合函数,其实都是reduce里面的一些特殊情况)

常见的 count 、sum 、avg 、max 、min 等函数就是一种聚合操作,我的理解是因为这些操作比较常用所以封装出来一个函数,这里就和reduce一起记录吧。
Collectors提供的于数据统计方法
统计:count
最值:maxBy、minBy
平均值:averagingInt、averagingLong、averagingDouble
求和:summingInt、summingLong、summingDouble
统计以上所有:summarizingInt、summarizingLong、summarizingDouble

List<Integer> list = Arrays.asList(11, 22, 33, 23, 18, 15, 2);
// 求总数
Long count = personList.stream().collect(Collectors.counting());
// 求最大元素
Optional<Integer> max = personList.stream().map(list).collect(Collectors.maxBy(Integer::compare));
// 求平均
Double average = personList.stream().collect(Collectors.averagingDouble(list));
// 求元素之和
Integer sum = personList.stream().collect(Collectors.summingInt(list));

Collectors类提供的reducing方法和stream本身的reduce方法比较,增加了自定义归约。

// reduce
Optional<Integer> sum = list.stream().reduce(Integer::sum);
//对元素进行自定义操作,比如每个元素-1
Integer sum = list.stream().reduce(0, (a, b) -> (a + b - 1));
4.sorted(排序)
//有实体类:User{name,salary,age,sex};
List<User> userList = new ArrayList<User>();
userList.add(new Object("甲", 11000, 23, "男"));
userList.add(new Object("乙", 9500, 24, "女"));
userList.add(new Object("丙", 9500, 25, "女"));
userList.add(new Object("丁", 10000, 23, "男"));
userList.add(new Object("戊", 15000, 26, "男"));
//sorted():自然排序,方法实现了Comparable接口,默认升序
List<String> nameList = userList.stream().sorted(Comparator.comparing(User::getSalary))
	.map(User::getName)
        .collect(Collectors.toList());
//sorted(Comparator cpr):Comparator排序器自定义排序,先按薪资再按年龄升序排序
        List<String> nameList1 = userList.stream()
            .sorted(Comparator.comparing(User::getSalary).thenComparing(User::getAge))
	    .map(User::getName)
            .collect(Collectors.toList());
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值