Java 8 添加了一个新的抽象概念——流(stream),它可以更加高效简洁的处理 集合 中的数据。
关于流的 特点 有:
- 不存储元素,根据需求直接进行计算。流水线操作,可以在流水线上进行相关操作,流水完成就无法进行任何操作。惰性执行,在流中间进行操作时,该操作会被记录,但不会执行,只有在流水完成时才会真正执行。内部迭代,不需要自己写迭代的代码。
因为是流是流水线操作,在中间和结束位置都可以操作,所以流的操作分为 中间操作 和 终结操作。
中间操作:分为 无状态操作 和 有状态操作,中间操作会返回一个新的流,但只有在终结操作之后才会执行(惰性执行)。无状态操作是指对元素的处理不受之前元素的影响,有状态操作是指该操作只有拿到全部的元素才能继续进行。
终结操作:分为 非短路操作 和 短路操作,该当该流执行完后,返回最终结果。非短路操作是指必须对所有元素进行处理后才能返回结果,短路操作是指遇到某些指定条件就直接返回结果,类似于 if...return 无需处理后面的元素。
流的相关使用 创建流的方式:直接创建:
//直接创建流 Streamstream01 = Stream.of(1, 1, 4, 5, 1, 4);
通过集合创建:
//创建集合 List流的中间操作:list = new ArrayList<>(); //通过集合创建流 Stream stream02 = list.stream();
public abstract Stream
filter(java.util.function.Predicate super T> predicate)
使用 Predicate 接口,通过指定条件来过滤元素。(下面代码使用了 forEach 来输出,关于 forEach 可以看后面的终结操作)。
//直接创建流 Streamstream = Stream.of(1, 1, 4, 5, 1, 4); //使用filter()方法 筛选大于3的元素 stream.filter(x -> x > 3).forEach(System.out::println);
执行结果:
public abstract
Stream map(java.util.function.Function super T, ? extends R> mapper)
使用 Function 接口,用于映射每个元素对应的结果。
//直接创建流 Streamstream = Stream.of(1, 1, 4, 5, 1, 4); //使用map()方法将集合的元素进行平方 stream.map(x -> x * x).forEach(x -> System.out.print(x + " "));
执行结果:
public abstract
Stream flatMap(java.util.function.Function super T, ? extends Stream extends R>> mapper)
使用 Function 接口,用于将多个流连成一个流,多用于进行升维降维操作。(下面代码使用了 collect() 来将元素汇总成集合,详见后面终结操作)。
//直接创建流 Streamstream = Stream.of(1); //创建集合 List li = Arrays.asList(0, 8, 0, 8, 7, 0, -1); //使用flatMap()方法利用两个一维集合生成一个二维集合 List > list = stream.flatMap(x -> li.stream().map(y -> Arrays.asList(x, y, x+y))).collect(Collectors.toList()); //打印 for(List
i: list){ for(int j: i){ System.out.print(j+"t"); } System.out.println(); }
执行结果:
public abstract Stream
distinct()
用于去掉重复元素。
//直接创建流 Streamstream = Stream.of(1, 9, 1, 9, 8, 1, 0); //使用distinct()方法进行去重 stream.distinct().forEach(x -> System.out.print(x + " "));
执行结果:
public abstract Stream
sorted()
对流中元素进行升序排序。
//直接创建流 Streamstream = Stream.of(1, 9, 1, 9, 8, 1, 0); //使用sorted()方法进行排序 stream.sorted().forEach(x -> System.out.print(x + " "));
执行结果:
public abstract Stream
peek(java.util.function.Consumer super T> action)
使用 Consumer 接口,主要用于进行 debug 操作,没有输出。
//直接创建流 Streamstream = Stream.of(1, 9, 1, 9, 8, 1, 0); //使用peek()方法检查排序之前的元素和排序之后的元素 List list = stream.peek(x -> System.out.print(x + " ")).sorted().peek(x -> System.out.print(" " + x)).collect(Collectors.toList());
执行结果:
public abstract Stream
limit(long maxSize)
返回前指定数目的元素。
//直接创建流 Streamstream = Stream.of(1, 9, 1, 9, 8, 1, 0); //使用limit()方法取前五个元素 stream.limit(5).forEach(x -> System.out.print(x + " "));
执行结果:
public abstract Stream
skip(long n)
跳过前指定数目的元素,返回后面的元素。
//直接创建流 Streamstream = Stream.of(1, 9, 1, 9, 8, 1, 0); //使用limit()方法忽略前五个元素 stream.skip(5).forEach(x -> System.out.print(x + " "));
执行结果:
终结操作:public abstract void forEach(java.util.function.Consumer super T> action)
使用 Consumer 接口,用于遍历,不返回值。
//直接创建流 Streamstream = Stream.of(1, 9, 1, 9, 8, 1, 0); //使用forEach()输出集合中的元素 stream.forEach(x -> System.out.print(x + " "));
执行结果:
public abstract void forEachOrdered(java.util.function.Consumer super T> action)
同 forEach(),但 forEach() 是并行处理的,输出不稳定但是更快,forEachOrder是按顺序处理的。
public abstract Object[] toArray()
用于将元素汇集到一个数组中。
//直接创建流 Streamstream = Stream.of(1, 1, 4, 5, 1, 4); //使用toArray()方法将元素汇集成一个数组 Object[] arr = stream.toArray(); //打印 for(Object i: arr){ System.out.print(i + " "); }
执行结果:
public abstract
R collect(java.util.stream.Collector super T, A, R> collector)
用于将元素汇集到一个集合中。
//直接创建流 Streamstream = Stream.of(1, 1, 4, 5, 1, 4); //使用collect()将元素汇集成一个集合 List list = stream.collect(Collectors.toList()); //打印 for(int i: list){ System.out.print(i + " "); }
执行结果:
public abstract java.util.Optional
reduce(java.util.function.BinaryOperator accumulator)
使用 BinaryOperator 接口,进行聚合操作,两个入参,一个返回值,用于对集合中两两元素依次进行操作。(ifPresent() 在这里的作用同 forEach())
//直接创建流 Streamstream = Stream.of(1, 1, 4, 5, 1, 4); //使用toArray()方法将元素汇集成一个数组 stream.reduce((x, y) -> x * y).ifPresent(x -> System.out.print(x + " "));
执行结果:
public abstract java.util.Optional
min(java.util.Comparator super T> comparator)
public abstract java.util.Optional
max(java.util.Comparator super T> comparator)
使用 Comparator 比较器,min() 用于返回集合中的最小值,max() 返回最大值。
//直接创建流 Streamstream = Stream.of(1, 1, 4, 5, 1, 4); //使用min()方法返回最小值 stream.min(Comparator.comparing(Integer::valueOf)).ifPresent(System.out::println); //重新创建流 Stream stream2 = Stream.of(1, 1, 4, 5, 1, 4); //使用max()方法返回最大值 stream2.max(Comparator.comparing(Integer::valueOf)).ifPresent(System.out::println);
执行结果:
public abstract long count()
用于统计元素的数量。
//直接创建流 Streamstream = Stream.of(1, 1, 4, 5, 1, 4); //使用count()方法返回元素的个数 System.out.println(stream.count());
执行结果:
public abstract boolean anyMatch(java.util.function.Predicate super T> predicate)
使用 Predicate 接口,用于检查列表中是否有元素满足给定条件。
//直接创建流 Streamstream = Stream.of(1, 1, 4, 5, 1, 4); //使用anyMatch()方法判断集合中是否有5 System.out.println(stream.anyMatch(x -> x == 5));
执行结果:
public abstract boolean allMatch(java.util.function.Predicate super T> predicate)
使用 Predicate 接口,用于检查列表中的所有元素是否都满足给定条件。
//直接创建流 Streamstream = Stream.of(1, 1, 4, 5, 1, 4); //使用allMatch()方法判断集合中是否都大于1 System.out.println(stream.allMatch(x -> x > 1));
执行结果:
public abstract boolean noneMatch(java.util.function.Predicate super T> predicate)
使用 Predicate 接口,用于检查列表中是否没有元素满足给定条件。
//直接创建流 Streamstream = Stream.of(1, 1, 4, 5, 1, 4); //使用allMatch()方法判断集合中是否都不小于1 System.out.println(stream.noneMatch(x -> x < 1));
执行结果:
public abstract java.util.Optional
findFirst()
用于返回数据流中的第一个元素。
//直接创建流 Streamstream = Stream.of(1, 1, 4, 5, 1, 4); //使用findFirst()方法找到数据流中的第一个元素 stream.findFirst().ifPresent(System.out::print);
执行结果:
public abstract java.util.Optional
findAny()
用于返回数据流中的任意一个元素,很多时候是返回第一个,但无法保证。
//直接创建流 Streamstream = Stream.of(1, 1, 4, 5, 1, 4); //使用findFirst()方法找到数据流中的第一个元素 stream.findAny().ifPresent(System.out::print);
执行结果:
小结实践是检测真理的唯一标准,多上手实践才能真正理解这些知识,去将那些不完美的代码变成你所期待的样子吧!



