stream操作常用API 示例详解
创始人
2024-05-22 19:58:31
0

简介

从JDK8开始,增加了一新特性Stream流式操作,Stream中提供了非常多的API供大家使用,灵活的使用这些API,可以非常的方便且优美的实现我们的代码逻辑。

流式操作主要用来处理数据(比如集合),就像泛型也大多用在集合中一样。下面我们主要用例子来介绍下,流的基操。

:本博客相关代码请参考:Scott 数据 映射 MySQL

最终型

toArray

toArray:将流转换为数组。

示例:

@Test
public void fun5() {List list = List.of("zhangsan", "lisi", "wanger", "mazi");Object[] array = list.stream().toArray();for (int i = 0; i < array.length; i++) {System.out.println(array[i]);}
}

结果:
image.png

collect

collect:将流转换为指定的类型,比如List转换为Set。

示例:

@Test
public void fun1(){String[] data = {"zhangsan","lisi","wanger","mazi"};List list = Arrays.stream(data).collect(Collectors.toList());System.out.println(list);Set set = Arrays.stream(data).collect(Collectors.toSet());System.out.println(set);
}

结果:
image.png

reduce

reduce:将元素合并起来,得到一个新值。可以简单理解为将一个数组或集合转换成一个String或integer类型的一个对象,最终结果为一个新值。
语法:reduce(a,(b,c)->{b+c})

  • a:规约初始值
  • b:阶段性的累加结果
  • c:当前遍历的元素
    注:若是整数类型求和 (Integer),b和c 可换成方法引用 Integer::sum

示例:

@Test
public void fun4() {String[] data = {"zhangsan", "lisi", "wanger", "mazi"};String reduce1 = Arrays.stream(data).reduce("", (v1, v2) -> v1 + v2);System.out.println(reduce1);Integer reduce2 = depts.stream().map(Dept::getDeptno).reduce(0, Integer::sum);System.out.println(reduce2);
}

结果:
image.png

iterator

iterator:将流转换为一个迭代器。

示例:

@Test
public void fun6() {List list = List.of("zhangsan", "lisi", "wanger", "mazi");Iterator iterator = list.stream().iterator();while (iterator.hasNext()){System.out.println(iterator.next());}
}

结果:
image.png

foreach

foreach:对流中的元素逐个遍历。
示例:

@Test
public void fun7() {List list = List.of("zhangsan", "lisi", "wanger", "mazi");list.stream().forEach(System.out::println);
}

结果:
image.png

anyMatch/allMatch/noneMatch

  • anyMatch:用于判断是否有符合匹配条件的元素。
  • allMatch:用于判断是否所有元素都符合匹配条件。
  • noneMatch:用于判断是否所有元素都不符合匹配条件。

示例:

@Test
public void fun8() {List list = List.of("zhangsan", "lisi", "wanger", "mazi");boolean b1 = list.stream().anyMatch(item -> item.contains("g"));System.out.println(b1);boolean b2 = list.stream().allMatch(item -> item.contains("g"));System.out.println(b2);boolean b3 = list.stream().noneMatch(item -> item.contains("g"));System.out.println(b3);
}

结果:
image.png

findFirst/findAny

  • findFirst:找到第一个匹配的元素后立即返回。
  • findAny:找到任何一个匹配的元素就返回。如果用在一个串行流中,跟findFirst效果一样。如果用在并行流中,就会比较高效。

示例:

@Test
public void fun9() {List list = List.of("zhangsan", "lisi", "wanger", "mazi");Optional first = list.stream().findFirst();System.out.println(first.get());Optional any = list.stream().findAny();System.out.println(any.get());int asInt = IntStream.range(10, 99).parallel().findAny().getAsInt();//并行System.out.println(asInt);
}

结果:
image.png

max/min

  • max:匹配元素最大值并返回。
  • min:匹配元素最小值并返回。

示例:

@Test
public void fun10() {int[] data = {88,23,45,92,18,46,78};OptionalInt max = Arrays.stream(data).max();System.out.println(max.getAsInt());OptionalInt min = Arrays.stream(data).min();System.out.println(min.getAsInt());
}

结果:
image.png

count

count:统计元素的个数,不会自动去重。
示例:

@Test
public void fun11() {List list = List.of("zhangsan", "lisi", "wanger", "mazi", "lisi", "qianwu");long count = list.stream().count();System.out.println(count);
}

结果:
image.png

中间型

filter

filter:按照指定的条件匹配出符合要求的元素,并返回一个新的stream流。
示例:

@Test
public void fun12() {List list = List.of("zhangsan", "lisi", "wanger", "mazi");List res = list.stream().filter(item -> item.length() > 4).collect(Collectors.toList());System.out.println(res);
}

结果:
image.png

map

map:将一个对象转换为另一个对象,并返回一个新的stream流。比如,可以把数组中的元素从一种类型转换成另一种类型,也可以将多类型的集合变成单纯的只有一种类型的集合。

示例:

@Test
public void fun3(){String[] data = {"zhangsan","lisi","wanger","mazi"};List list = Arrays.stream(data).map(String::length).collect(Collectors.toList());System.out.println(list);
}

结果:
image.png

示例:

@Test
public void fun4() {List list = depts.stream().map(Dept::getDeptno).collect(Collectors.toList());System.out.println(list);
}

结果:
image.png

flatMap

flatMap:将已有的对象转换为另一个对象,它是一个一对多的逻辑。简单来说就是将多个stream流合并成一个stream。
flatMap与map的区别在于:

  • map是一对一的,即将一个对象转换为另一个对象
  • flatMap是一对多的,即将一个对象拆分对多个对象

示例:

@Test
public void fun17() {List dept1 = new ArrayList<>();dept1.add(new Dept(10, "ACCOUNTING", "NEWYORK"));dept1.add(new Dept(20, "RESEARCH", "DALLAS"));List dept2 = new ArrayList<>();dept2.add(new Dept(30, "SALES", "CHICAGO"));dept2.add(new Dept(40, "OPERATIONS", "BOSTON"));//map 一对一 映射处理dept1.stream().map(dept -> {Dept build = dept.builder().deptno(dept.getDeptno() * 2).dname(dept.getDname().toLowerCase()).loc(dept.getLoc().toLowerCase()).build();return build;}).toList().forEach(System.out::println);List> depts = new ArrayList<>();depts.add(dept1);depts.add(dept2);//flatMap  一对多映射处理,深入到多个stream内部去处理子元素,统一输出depts.stream().flatMap(item -> item.stream().filter(dept -> dept.getDeptno() > 20)).toList().forEach(System.out::println);
}

结果:
image.png


map和flatMap都可以将一个流的元素按照一定的映射规则映射到另一个流中:

  • map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
  • flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。
    image.png

示例:

@Test
public void fun16() {List list = List.of("zhangsan", "lisi", "wanger", "mazi");//接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。List res1 = list.stream().map(String::toUpperCase).toList();System.out.println(res1);//接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。List collect = list.stream().flatMap(item -> {String[] split = item.split("");Stream stream = Arrays.stream(split);return stream;}).collect(Collectors.toList());System.out.println(collect);
}

结果:
image.png

peek

peek:对流中的元素逐个遍历处理,它与map的区别在于:map一般用于对象的转换,peek用于对象的消费,即不改变元素本身的类型。
示例:

@Test
public void fun13() {List list2 = Arrays.asList(1,2,3,4);list2.stream().peek(x -> System.out.println("stream: " + x)) //peek是对元素逐一消费.map(x -> x * 2) //map是对元素进行转换.peek(x -> System.out.println("map: " + x)).collect(Collectors.toList());
}

结果:
image.png

示例:

@Test
public void fun14() {List list = List.of("zhangsan", "lisi", "wanger", "mazi");// 使用peek操作流,流中的元素没有改变。list.stream().peek(String::toUpperCase).forEach(System.out::println);// 使用map操作流,流中的元素有改变。list.stream().map(String::toUpperCase).forEach(System.out::println);
}

结果:
image.png

limit/skip

  • limit:就相当于sql中的limit,可以指定保留前N的元素。
  • skip:作用与limit相反,会抛弃前N的元素。

示例:

@Test
public void fun18() {List list = List.of("zhangsan", "lisi", "wanger", "mazi","qianwu","zhaoliu");list.stream().limit(3).toList().forEach(System.out::println);list.stream().skip(2).toList().forEach(System.out::println);
}

结果:
image.png

sorted

sorted:用于对流中的数据排序
示例:

@Test
public void fun22() {List list = List.of("zhangsan", "lisi", "wanger", "mazi");list.stream().sorted(Comparator.comparingInt(String::length)).toList().forEach(System.out::println);
}

结果:

concat

concat:可以将多个流的数据合并为一个流。
示例:

@Test
public void fun20() {List list1 = List.of("zhangsan", "lisi", "wanger");List list2 = List.of("mazi","qianwu","zhaoliu");Stream.concat(list1.stream(),list2.stream()).toList().forEach(System.out::println);}

结果:
image.png

distinct

distinct:用于对流中的元素去重。
示例:

@Test
public void fun21() {List list = List.of("zhangsan", "lisi", "wanger", "mazi","lisi","mazi");list.stream().distinct().toList().forEach(System.out::println);
}

结果:
image.png

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...