Java 8 新API Steam
学习自廖雪峰网站 Java教程 - 使用Stream
小结
Stream API的特点是:
- Stream API提供了一套新的流式处理的抽象序列;
- Stream API支持函数式编程和链式操作;
- Stream可以表示无限序列,并且大多数情况下是惰性求值的。
Map、Filter、Reduce
map()
map()跟JS高级函数map()差不多,所有字符串根据映射规则,生成一个新流
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.stream().forEach(System.out::println);//基本流元素遍历,无限的要加限制
list.stream().map(n -> n + "!").forEach(System.out::println);//给流里面的每个字符串加`!`,生成新流
}
filter()
filter()也跟JS的filter差不多,满足条件的才加入新流。
public static void main(String[] args) {
System.out.println("-----------------------");
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbbb");
list.add("ccccc");
Stream<String> s = list.stream();
s.forEach(System.out::println);//基本流元素遍历,无限的要加限制
s.map(n -> n + "!").forEach(System.out::println);//给流里面的每个字符串加`!`,生成新流
s.filter(n -> n.length() != 4).forEach(System.out::println);//流中字符串长度为4的被过滤
}
reduce()
map()
和filter()
都是Stream
的转换方法,而Stream.reduce()
则是Stream
的一个聚合方法,它可以把一个Stream
的所有元素按照聚合函数聚合成一个结果。
public static void main(String[] args) {
System.out.println("-----------------------");
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbbb");
list.add("ccccc");
//将流中的字符用'_'拼接成一个字符。其中acc是上次计算返回的结果,n是当前元素
String reduce = list.stream().reduce("", (acc, n) -> acc + n + "_");
System.out.println(reduce);
//反向拼接
String reduce1 = list.stream().reduce("", (acc, n) -> "_" + n + acc);
System.out.println(reduce1);
}
廖雪峰的案例
public class Main {
public static void main(String[] args) {
// 按行读取配置文件:
List<String> props = List.of("profile=native", "debug=true", "logging=warn", "interval=500");
Map<String, String> map = props.stream()
// 把k=v转换为Map[k]=v:
.map(kv -> {
String[] ss = kv.split("\=", 2);
return Map.of(ss[0], ss[1]);
})
// 把所有Map聚合到一个Map:
.reduce(new HashMap<String, String>(), (m, kv) -> {
m.putAll(kv);
return m;
});
// 打印结果:
map.forEach((k, v) -> {
System.out.println(k + " = " + v);
});
}
}
输出集合和其他操作
输出集合
此外Stream还有toArray()、输出为Map,分组输出的方法
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("abbbb");
list.add("bccccc");
System.out.println(Arrays.toString(list.stream().toArray()));
System.out.println(list.stream().collect(Collectors.toMap(
//s的前两个字符作为key
s -> s.substring(0, 2),
// 把元素s映射为value:
s -> s)
));
Map<String, List<String>> groups = list.stream()
.collect(Collectors.groupingBy(s -> s.substring(0, 1)/*函数1:key or 分组名*/, Collectors.toList()/*函数2:分组的value 表示输出为List*/));
System.out.println(groups);
}
其他操作
元素排序用sorted()
方法并会产生新的流,如果要自定义排序,传入指定的Comparator
即可
steam().sorted(String::compareToIgnoreCase)
去重.distinct()
、截取.skip(2).limit(3)
跳过前两个,然后取3个、合并Stream.concat(s1, s2);
并行.parallel()
,经过parallel()
转换后的Stream
只要可能,就会对后续操作进行并行处理。
其他聚合方法
所有流都有count()
,max(Comparator<? super T> cp)
,``min(Comparator<? super T> cp)`方法
对于数字类的,还提供了sum()、average()
方法。