本篇文章为你整理了【java8】stream学习笔记()的详细内容,包含有 【java8】stream学习笔记,希望能帮助你了解 【java8】stream学习笔记。
目录一、什么是Stream二、Stream的特点串并行干扰数据源无状态排序三、创建Stream四、中间操作1. distinct2. filter3. map4. mapToDouble4. flatmap5. limit6. skip7. peek8. sorted五、终点操作1. Match2. count3. collect4. find5. forEach6. max、min7. reduce8. toArray()六、参考文档
一、什么是Stream
Stream是java8的新增特性,表示数据流。
二、Stream的特点
不存储数据:流是基于数据源的对象,本身不存储数据。
函数式编程:流的操作不会修改数据源。
延迟操作:流的很多操作如filter、map是延迟执行的,只有到了终点操作才会将操作顺序执行。
可以解绑:对于无线数量的流,有些操作(如limit(n)、findFirst())可以实现“短路操作”,访问到有限的元素后就可以返回。
纯消费:流只能被消费一次。如果使用完了一次流,仍然用这个流对象来操作时,会报异常。
所有的流操作都可以串行执行或者并行执行。除非显示的创建并行流,否则默认创建串行流。
串行:Collection.stream()、IntStream.range(int, int)
并行:Collection.parallelStream()、
通过parallel()方法可以将串行流转换为并行流,sequential()方法将流转换为串行流
干扰数据源
流可以从非线程安全的集合中创建。当流执行时,非并发的数据源不应该改变,否则会抛出java.util.ConcurrentModificationException异常。
大部分流的操作的参数都是函数式接口,可以使用Lambda表达式实现。它们用来描述用户的行为,称之为行为参数(behavioral parameters)。
如果这些行为参数有状态,则流的操作的结果可能是不确定的,比如下面的代码:
下面代码在并行执行时,由于执行顺序的不确定性,state.s的改变时机可能不同,导致多次执行时的结果不同
List String l = new ArrayList(Arrays.asList("one", "two", ……));
class State {
boolean s;
final State state = new State();
Stream String sl = l.stream().map(e - {
if (state.s)
return "OK";
else {
state.s = true;
return e;
sl.forEach(System.out::println);
某些流的返回元素是有确定顺序的。这取决于它的数据源和中间操作。
比如List和Array创建的流是有序的,而HashSet创建的流是无序的。
sort()方法可以将流变得有序,而unordered()可以将流无序(不会打散元素)
当流有序时,如果用户并不关心顺序,可以使用unordered显示的去掉流的有序约束,可以改善某些情况下的并行性能
三、创建Stream
常见创建流的方法:
通过集合Collection的Stream()或parallelStream():如list.parallelStream()、Arrays.asList(1,2,3).stream()。
通过数组Arrays.stream(Object[])方法:如Arrays.stream(new int[]{1,2,3})。
流的静态方法:如:Stream.of(Object[])、IntStream.range(int, int)、Stream.iterate(Object, UnaryOperator)。
随机数流Random.ints()。
四、中间操作
中间操作是延迟执行的,不会修改原始数据流,在终点操作开始时才会开始执行
1. distinct
根据流中元素的hashCode()和equals()方法去除重复元素
List Integer list = Arrays.asList(1, 2, 3, 4, 4, 4, 5, 6);
list.stream().distinct().forEach(System.out::print); // 123456
System.out.println();
list.forEach(System.out::print); // 12344456
2. filter
接收predicate,过滤数据
// 筛选出偶数
List Integer list = Arrays.asList(1, 2, 3, 4, 4, 4, 5, 6);
list.stream().filter(e - e % 2 == 0).forEach(System.out::print); // 24446
3. map
接收一个Function实例,重新印射数据
// 加1
List Integer list = Arrays.asList(1, 2, 3, 4, 4, 4, 5, 6);
list.stream().map(e - e + 1).forEach(System.out::print); // 23455567
4. mapToDouble
类似map,不过结果一定要是Double类型。
类似的方法还有mapToInt(),mapToLong()
// 加1.1
List Integer list = Arrays.asList(1, 2, 3, 4, 4, 4, 5, 6);
list.stream().mapToDouble(e - e + 1.1).forEach(System.out::println);
// 加1
List Integer list = Arrays.asList(1, 2, 3, 4, 4, 4, 5, 6);
list.stream().mapToDouble(e - e + 1).forEach(System.out::println);
4. flatmap
R Stream R flatMap(Function ? super T, ? extends Stream ? extends R mapper);
将映射后的元素放在一个新的流中。
类似的方法还有flatMapToDouble、flatMapToInt、flatMapToLong
List String list = Arrays.asList("1233", "2444", "562","78");
list.stream()
.flatMap(e - Arrays.stream(e.split("2")))
.forEach(System.out::println);
5. limit
限制流中元素的数量。对于有序并行流,性能消耗更高
List Integer list = Arrays.asList(1, 2, 3, 4, 4, 4, 5, 6);
list.stream().limit(5).forEach(System.out::print); // 12344
6. skip
丢弃前n个元素,返回流。
System.out.println("-----------------------");
list.stream().skip(6).forEach(System.out::println);
System.out.println("-----------------------");
list.stream().skip(8).forEach(System.out::println);
-----------------------
-----------------------
7. peek
接收一个Consumer,对元素做某些操作,但是并不会修改数据(对象数据可能会被修改)。一般用于debug
List Integer list = Arrays.asList(8, 1, 0, 9, 7, 5);
list.stream().peek(System.out::print).count(); // 810975
8. sorted
将流中的元素按自然顺序排序。可以自定义比较器。
System.out.println("升序: ");
List Integer list = Arrays.asList(8, 1, 0, 9, 7, 5);
list.stream().sorted().forEach(System.out::print);
System.out.println();
System.out.println("降序: ");
list.stream().sorted((x, y) - y - x).forEach(System.out::print);
015789
987510
五、终点操作
1. Match
有allMatch(Predicate p)、anyMatch(Predicate p)、noneMatch(Predicate p)三种方法。
返回boolean。
List Integer list = Arrays.asList(8, 1, 0, 9, 7, 5);
// allMatch 是否全部符合
System.out.println(list.stream().allMatch(x - x -1)); // true
System.out.println(list.stream().allMatch(x - x 1)); // false
// anyMatch 是否至少有一个符合
System.out.println(list.stream().anyMatch(x - x == -1)); // false
System.out.println(list.stream().anyMatch(x - x == 1)); // true
// noneMatch 是否全部不符合
System.out.println(list.stream().noneMatch(x - x 5)); // false
System.out.println(list.stream().noneMatch(x - x 9)); // true
2. count
返回流中元素的数量。返回long
List Integer list = Arrays.asList(8, 1, 0, 9, 7, 5);
System.out.println(list.stream().count()); // 6
3. collect
传入Collectors中的接口实现,将流转化为其他形式的数据。部分接口:
toList、toSet 转化为list或set
counting 计数
reducing 化简
maxBy、minBy 最大值最小值
summingInt 求和
joining 字符串连接
List Integer list = Arrays.asList(8, 1, 0, 9, 7, 5);
// 转化为list格式
List Integer res1 = list.stream().collect(Collectors.toList());
// 转化为set格式
Set Integer res2 = list.stream().collect(Collectors.toSet());
4. find
有findFirst()和findAny()两种。返回Optional对象
Optional T findFirst();
List Integer list = Arrays.asList(8, 1, 0, 9, 7, 5);
Optional Integer integer = list.stream().findFirst();
System.out.println(integer.get()); // 8
// findAny()对于串行流:一般返回第一个结果
integer = list.stream().findAny();
System.out.println(integer.get()); // 8
// findAny()对于并行流,多次执行会随机返回结果
integer = list.parallelStream().findAny();
System.out.println(integer.get()); // 随机打印
5. forEach
遍历流中元素,执行指定操作
List Integer list = Arrays.asList(8, 1, 0, 9, 7, 5);
List Integer res = new ArrayList ();
list.stream().forEach(e - res.add(e + 2));
System.out.println(list.toString());
// [10, 3, 2, 11, 9, 7]
6. max、min
最大值、最小值。返回Optional对象
将元素按比较器排序,然后min返回第一个数,max返回最后一个数
List Integer list = Arrays.asList(8, 1, 0, 9, 7, 5);
// 升序排序 015789
System.out.println(list.stream().min((x, y) - x - y).get()); // 0
System.out.println(list.stream().max((x, y) - x - y).get()); // 9
// 降序排序 987510
System.out.println(list.stream().min((x, y) - y - x).get()); // 9
System.out.println(list.stream().max((x, y) - y - x).get()); // 0
7. reduce
将元素数据结合后返回。
List Integer list = Arrays.asList(8, 1, 0, 9, 7, 5);
// 默认返回Optional类型数据
Optional Integer res1 = list.stream().reduce(Integer::sum);
System.out.println(res1.get());
// 指定返回数据类型为Integer
Integer res2 = list.stream().reduce(0, Integer::sum);
System.out.println(res2);
8. toArray()
将流中的元素保存到数组中
A A[] toArray(IntFunction A[] generator);
List Integer list = Arrays.asList(8, 1, 0, 9, 7, 5);
Integer[] ints = list.stream().map(e - e + 1).toArray(Integer[]::new);
for (Integer integer : ints) {
System.out.println(integer);
六、参考文档
https://colobu.com/2016/03/02/Java-Stream/
https://juejin.cn/post/6844903646648336397#heading-9
以上就是【java8】stream学习笔记()的详细内容,想要了解更多 【java8】stream学习笔记的内容,请持续关注盛行IT软件开发工作室。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。