Stream
和List
不一样,List
存储的每个元素都是已经存储在内存中的某个Java对象,而Stream
输出的元素可能并没有预先存储在内存中,而是实时计算出来的。
Stream API的基本用法就是:创建一个Stream
,然后做若干次转换,最后调用一个求值方法获取真正计算的结果:
int result = createNaturalStream()// 创建Stream
.filter(n -> n % 2 == 0)// 任意个转换
.map(n -> n * n)// 任意个转换
.limit(100)// 任意个转换
.sum();// 最终计算结果
Stream API的特点是:
Stream.of()
静态方法
Stream<String> stream = Stream.of("A", "B", "C", "D");
// forEach()方法相当于内部循环调用,
// 可传入符合Consumer接口的void accept(T t)的方法引用:
stream.forEach(System.out::println);
基于数组或者 Collection
Stream<String> stream1 = Arrays.stream(new String[] { "A", "B", "C" });
Stream<String> stream2 = List.of("X", "Y", "Z").stream();
stream1.forEach(System.out::println);
stream2.forEach(System.out::println);
基于 Supplier
public class Main {
public static void main(String[] args) {
Stream<Integer> natual = Stream.generate(new NatualSupplier());
// 注意:无限序列必须先变成有限序列再打印:
natual.limit(20).forEach(System.out::println);
}
}
class NatualSupplier implements Supplier<Integer> {
int n = 0;
public Integer get() {
n++;
return n;
}
}
其他方法
使用 Files 提供的方法按行便利文本:Stream<String> lines = Files.lines(Paths.get("/path/to/file.txt"))
使用正则表达式将长字符串分割成 Stream 序列
Pattern p = Pattern.compile("\\\\s+");
Stream<String> s = p.splitAsStream("The quick brown fox jumps over the lazy dog");
s.forEach(System.out::println);
<aside>
💡 因为Java的范型不支持基本类型,所以我们无法用Stream<int>
这样的类型,会发生编译错误。为了保存int
,只能使用Stream<Integer>
,但这样会产生频繁的装箱、拆箱操作。为了提高效率,Java标准库提供了IntStream
、LongStream
和DoubleStream
这三种使用基本类型的Stream
,它们的使用方法和范型Stream
没有大的区别,设计这三个Stream
的目的是提高运行效率:
// 将int[]数组变为IntStream:
IntStream is = Arrays.stream(newint[] { 1, 2, 3 });
// 将Stream<String>转换为LongStream:
LongStream ls = List.of("1", "2", "3").stream().mapToLong(Long::parseLong);
</aside>
Stream<Integer> s = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> s2 = s.map(n -> n * n);
使用 map()
方法可以处理流中的每一个元素
public class Main {
public static void main(String[] args) {
List.of(" Apple ", " pear ", " ORANGE", " BaNaNa ")
.stream()
.map(String::trim) // 去空格
.map(String::toLowerCase) // 变小写
.forEach(System.out::println); // 打印
}
}
使用 filter()
方法可以过滤掉集合中的部分元素