Java流是一连串的元素序列,可以进行各种操作以实现数据的转换和处理。流式编程的概念基于函数式编程的思想,旨在简化代码,提高可读性和可维护性。
目录
1.5 I/O类Files的list、find、lines和walk方法创建Stream对象
2.21 并行求和:parallel()和 reduce()结合使用
2.22 转换类型流:mapToInt()、mapToDouble()、MapToLong()
一、创建流对象
1.1 List 转流对象
java.util.List<Integer> list = Arrays.asList(1, 2, 3 ,4);
Stream<Integer> stream = list.stream();
1.2 数组转流对象
Integer[] arr = {1,2,3};
Stream<Integer> stream = java.util.Arrays.stream(arr);
1.3 通过Stream.of来创建
Stream<Integer> stream = Stream.of(1, 2, 3, 4);
1.4 通过Stream.builder来创建
// 若不确定要添加多少个元素到Stream中,可用Stream.builder()来创建Stream.builder()对象。用add方法来添加元素,然后用build方法来生成Stream对象。
Stream.Builder<Integer> builder = Stream.builder();
builder.add(1);
builder.add(2);
builder.add(3);
Stream<Integer> build = builder.build();
1.5 I/O类Files的list、find、lines和walk方法创建Stream对象
Stream<Path> stream = Files.list(Paths.get("dirName"));
Stream<Path> matches = Files.find(inputDirs, Integer.MAX_VALUE, (path, attr) -> inputFile.equals(path), FileVisitOption.FOLLOW_LINKS);
Stream<String> lines = Files.lines(Paths.get("dirName"));
Stream<Path> paths = Files.walk(Paths.get("dirName"), 2)
1.6 通过生成器创建Stream对象
// 无限流,元素都为0
Stream<Integer> generate = Stream.generate(() -> 1);
// 无限流,从0 开始递增1
Stream<Integer> iterate = Stream.iterate(0, n -> n + 1);
二、操作方法
2.1 映射:map()
Stream<String> stream = Stream.of("1","2","3","4","5","6","7","8","9","10");
Stream<Integer> stream1 = stream.map(m -> Integer.valueOf(m));
2.2 排序:sorted()
Stream<Integer> stream = Stream.of(1,2,3,4,5,6);
// 降序
Stream<Integer> sorted = stream.sorted((a, b) -> b - a); // 6, 5, 4, 3, 2, 1
2.3 去重:distinct()
Stream<Integer> stream = Stream.of(1,1,4,4,4,4);
stream = stream.distinct(); // 1, 4
2.4 汇总:collect()
Stream<Integer> stream = Stream.of(1,1,4,4,4,4);
List<Integer> list = stream.collect(Collectors.toList());
2.5 过滤:filter()
Stream<Integer> stream = Stream.of(1,2,3,4,5,6);
stream = stream.filter(m -> m > 3); // 4, 5, 6
2.6 跳过:skip()
Stream<Integer> stream = Stream.of(1,2,3,4,5,6);
stream = stream.skip(4); // 截断前 4个元素,只剩 5, 6
2.7 截断:limit()
Stream<Integer> stream = Stream.of(1,2,3,4,5,6);
stream = stream.limit(4); // 只留前 4个元素,只剩 1, 2, 3, 4
2.8 扁平映射:flatMap()
List<List<Integer>> list = Arrays.asList(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6)); // 二维数据
Stream<Integer> stream = list.stream().flatMap(List::stream); // 二维映射成一维流 1, 2, 3, 4, 5, 6
2.9 归约:reduce()
// reduce()方法是对Stream流中所有元素求和
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
Optional<Integer> reduce = stream.reduce((a, b) -> a + b);
reduce.stream().forEach(m-> System.out.println(m)); // 21
2.10 统计:summaryStatistics()
IntStream intStream = IntStream.of(1, 2, 3, 4, 5, 6);
IntStream intStream2 = IntStream.of(5, 6, 7, 8);
IntSummaryStatistics stats = intStream.summaryStatistics();
IntSummaryStatistics stats2 = intStream2.summaryStatistics();
stats.getMax(); // 求最大值 6
stats.getMin(); // 求最小值 1
stats.getSum(); // 求和 21
stats.getCount(); // 求数量 6
stats.combine(stats2); // 两个stats 和 stat2 合并求以上四个参数到stats中 分别得 8, 1, 47, 10
stats.getAverage(); // 求平均值 4.7
2.11 遍历流元素:forEach()
IntStream intStream = IntStream.of(1, 2, 3, 4, 5, 6);
intStream.forEach(m-> System.out.println(m)); // 遍历打印出 1, 2, 3, 4, 5, 6
2.12 被建议在debug中使用的:peek()
Stream<Integer> stream = Arrays.asList(4, 7, 9, 11, 12).stream();
stream.peek(n -> System.out.println(n)); // 发现,没有任何输出,说明打印逻辑未执行。(注意可能隐藏逻辑BUG)
官方原文说明:In cases where the stream implementation is able to optimize away the production of some or all the elements (such as with short-circuiting operations like findFirst, or in the example described in count), the action will not be invoked for those elements.(在流实现能够优化部分或所有元素的生成的情况下(例如使用像findFirst这样的短路操作,或者在count中描述的示例中),将不会为这些元素调用操作。)
2.13 匹配所有:allMatch()
Stream<Integer> stream = Arrays.asList(4, 7, 9, 11, 12).stream();
boolean b = stream.allMatch(m -> m % 2 == 1); // false。必须全部都为奇数,才为 true
2.14 匹配任务一个:anyMatch()
Stream<Integer> stream = Arrays.asList(4, 7, 9, 11, 12).stream();
System.out.println(stream.anyMatch(m -> m % 2 == 1)); // true。只要有一个为奇数,则为true
2.15 都不满足:noneMatch()
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5); System.out.println(stream.noneMatch(m -> m > 8)); // true
Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5); System.out.println(stream1.noneMatch(m -> m > 3)); // false
2.15 取第一个元素:findFirst()
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5); System.out.println(stream.findFirst().get()); // 1
2.16 随机返回一个:findAny()
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5); System.out.println(stream.findAny().get()); // 返回1,数量比较大的时候不一定是1了,取决于并行处理的结果
2.17 求最大值:max()
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5); System.out.println(stream.max(Integer:: compareTo).get()); // 5
2.18 求最小值:min()
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5); System.out.println(stream.min(Integer:: compareTo).get()); // 1
2.19 求元素个数:count()
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
System.out.println(stream.count()); // 5
2.20 并行流:parallel()
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
stream.parallel().forEach(m-> System.out.println(m)); // 3, 5, 4, 1, 2 每次执行输出都不一样
2.21 并行求和:parallel()和 reduce()结合使用
Stream<Integer> stream = Stream.of(1, 2, 3 , 4 , 5 ,6, 7, 8, 9, 10); System.out.println(stream.parallel().reduce(0, Integer::sum)); // 55
2.22 转换类型流:mapToInt()、mapToDouble()、MapToLong()
Stream<Integer> stream = Stream.of(1, 2, 3 , 4 , 5 ,6, 7, 8, 9, 10);
IntStream intStream = stream.mapToInt(Integer::intValue);
// 转为IntStream流,便于操作int(),如求最大值 max(),最小值 min(),求和 sum() 和 转为数组 toArray() 等。
mapToDouble、mapToLong 与 mapToInt 使用相似。