1、迭代
我们在遍历集合时,通常会使用到for循环。for循环其实是封装了Iterator迭代器的语法糖。是一种外部迭代。
外部迭代很难抽象出一些我们需要的操作,从本质上讲,它是一种串行化操作。
另一种方法就是内部迭代,也就是Stream的操作。
stream的操作大体可以分为两种:过滤和计数。如以下代码:allArtists.stream().filter(artist -> artist.isFrom("London"));
只过滤,不计数。像 filter 这样只描述 Stream,最终不产生新集合的方法叫作惰性求值方法;而像 count 这样
最终会从 Stream 产生值的方法叫作及早求值方法。
下列代码只有惰性求值方法,所以程序并不会输出任何信息
allArtists.stream() .filter(artist -> {System.out.println(artist.getName());return artist.isFrom("London");});
如果在其加入一个拥有终止操作的流,则会被输出
long count = allArtists.stream() .filter(artist -> {System.out.println(artist.getName());return artist.isFrom("London");}).count();
如果返回值是 Stream, 那么是惰性求值;如果返回值是另一个值或为空,那么就是及早求值。
2、常用的流操作
collect(toList())
collect(toList())方法由Stream里的值生成一个列表,是一个及早求值操作
List<String> collected = Stream.of("a", "b", "c") // 生成列表.collect(Collectors.toList()); // 聚合成一个listassertEquals(Arrays.asList("a", "b", "c"), collected);
map
如果有一个函数可以将一种类型的值转换成另外一种类型,map 操作就可以使用该函数,将一个流中的值转换成一个新的流。
用map操作将字符串转为大写形式
List<String> collected = Stream.of("a", "b", "hello").map(string -> string.toUpperCase()).collect(toList());assertEquals(asList("A", "B", "HELLO"), collected);
filter
遍历数据并检查其中的元素时,可尝试使用 Stream 中提供的新方法 filter
List<String> beginningWithNumbers = Stream.of("a", "1abc", "abc1").filter(value -> isDigit(value.charAt(0))).collect(toList());
flatMap
flatMap 方法可用 Stream 替换值,然后将多个 Stream 连接成一个 Stream
将所有数字合成一个列表
List<Integer> together = Stream.of(asList(1, 2), asList(3, 4)).flatMap(numbers -> numbers.stream()).collect(toList());
max和min
求最大最小值
List<Track> tracks = asList(new Track("Bakai", 524),new Track("Violets for Your Furs", 378),new Track("Time Was", 451));Track shortestTrack = tracks.stream().min(Comparator.comparing(track -> track.getLength())).get();
reduce
int count = Stream.of(1, 2, 3).reduce(0, (acc, element) -> acc + element); // acc是累加器,保存着当前的累加结果assertEquals(6, count);
