Java Streaming Basic
10年前加入现在的公司的时候公司的产品还在用JDK5,写code自然完全不会用Lamda,Streaming这些8才出现的特性。
后来开始做micro service了,用到新版本的JDK,但是我也很少写code了。中间看了一些书,不过一直是似是而非。是时间仔细看下了。
Intermediate Operations
filter
limit
map
flatMap
Stream.map和Stream.flatMap的区别
先看signature. 区别是 flatMap穿进去一个Item,出来一个Stream:
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
这两个其实是完全不一样的东西,map就是把steam里面的item转换成另外一个,非常简单。flatMap是用来处理item也是list的情况,有时候我们想把两维列表转化成一个,就可以用这。下面是一个简单的例子:
List<List<String>> list = Arrays.asList(
Arrays.asList("a"),
Arrays.asList("b"));
System.out.println(list
.stream()
.flatMap(Collection::stream)
.collect(Collectors.toList()));
//https://www.baeldung.com/java-difference-map-and-flatmap
下面是项目的一个更加实际的例子:
Set<ObjectMetadataModel.FieldMapping> fields = metadataStore.getAllObjectsForDataSourceType(object.getDataSourceObject())
.stream()
.map(ObjectMetadataModel::getFields)
.flatMap(Collection::stream)
.collect(toSet());
这个例子是拿到一个父对象,父对象里面有子对象,这样就能拿到所有的子对象。
总的来说stream就是一个循环,而flatMap就是一个嵌套循环。
下面是另外一个lamda的例子(不是method reference):
//双重循环
for(Suit suit : Suit.values()){
for(Rank rank : Rank.values()){
result.add( new Card(suit, rank) );
}
}
//对应的stream
Stream.of(Suit.values())
.flatMap( suit -> Stream.of(Rank.values())
.map( rank -> new Card(suit.rank)))
.collect(toList()); // Collectors::toList
Terminal Operation
forEach
forEach其实就是iterate.不用改被用作计算,就是用简单的report,或者简单的操作比如把结果加到另一个colection里面. –<Effective Java>
collect
常用的的下面几种:
toList
toSet
toMap:如果有重复key,会出错。第三个参数可以用来去重。比如可以选择最大,选择最后的一个。
//选择销售额大的
toMap(keyMapper, valueMapper, maxBy(comparing(Album::sales)));
//选择最后的一个
toMap(keyMapper, valueMapper, (v1,v2) -> V2
groupingBy:Value可以是一个数组,也可以是summary,比如`counting()`.
String[] dd = {"absw","resa","eras","dds","basw","rr","rr"};
Arrays.stream(dd).collect(Collectors.groupingBy(e -> e.substring(0,1)))
.forEach((key, value) -> System.out.println("key:" + key + " value:" + value));
//output
key:a value:[absw]
key:b value:[basw]
key:r value:[resa, rr, rr]
key:d value:[dds]
key:e value:[eras]
Joining: 三个参数,join的delimiter, start character,end character
String chString = str.stream()
.map(String::valueOf)
.collect(Collectors.joining(", ", "{", "}"));
//Output:
{Geeks, for, Geeks}