3.1 从外部迭代到内部迭代
外部迭代
使用迭代器计算来自伦敦的艺术家人数:
int count=0;
for (Artist artist:allArtists){
if(artist.isFrom("London")){
count++;
}
}
这样的外部迭代本质上是一种串行化操作,并且会将行为和方法混为一谈。
内部迭代
使用内部迭代计算来自伦敦的艺术家人数:
long count=allArtists.stream().filter(artist->artist.isFrom("London")).count();
3.2 惰性求值和及早求值
惰性求值:
allArtists.stream().filter(artist->artist.isFrom("London"));
这行代码并没有做什么实际性的工作,filter只刻画出了stream,并没有产生新的集合,像filter这样只描述stream 最终不产生新集合的方法叫做惰性求值方法,而像count这样最终会从stream中产生值得方法叫做及早求值方法。
3.3 常用的流操作
(1) collect(toList())
collect(toList())方法由Stream里的值生成一个列表,是一个及早求值操作。
List<String> collected = Stream.of("a","b","c").collect(Collectors.toList());
(2) map
map 操作将一个流中的值转化为一个新的流。
List<String> collected = Stream.of("a","b","hello")
.map(str->str.toUpperCase()).collect(Collectors.toList());
(3) filter
遍历数据并检查其中的元素时,可以使用Stream中提供的新方法filter。
List<String> collected = Stream.of("a","1a,"c").filter(value->isDigit(value.charAt(0)))
collect(Collectors.toList());
(4) flatMap
flatMap()方法可用stream替换值,然后将多个stream 连接成一个stream。
看一个简单的例子,假设一个包含多个列表的流,现在希望得到所有数字的序列:
List<Integer> together = Stream.of(Arrays.asList(1,2),Arrays.asList(3,4))
.flatMap(numbers->numbers.stream())
.collect(Collectors.toList());
(5) max 和 min
Track shortest = tracks.stream().min(Comparator.comparing(track->track.getLength())).get();
(6) reduce
reduce 操作可以从一组值中生成一个值。
T reduce(T identity, BinaryOperator accumulator);
例子:使用reduce 求和:
int sum = Stream.of(1,2,3).reduce(0,(acc,element)->acc+element);
展开reduce 操作:
BinaryOperator<Integer> accumulator = (acc,element)->acc+element;
int sum = accumulator.apply(accumulator.apply(accumulator.apply(0,1),2),3);
(7) 例子:找出长度大于1分钟的曲目。
public Set<String> findLongTracks(List<Album> albums){
return albums.stream().flatMap(album -> album.getTracks()).filter(track -> track.getLength>60).map(track -> track.getName()).collect(Collectors.toSet());
}