1.11 下游收集器
下游收集器用来处理groupingBy产生的映射表中每一个值的列表。
列如,如果想要获得集而不是列表,那么可以使用上一节中看到的Collector.toSet收集器:
- 注意 需导入 import static java.util.stream.Collectors.*;
Map<String,Set<Locale>> countryToLocaleSet = locales.collect(
groupingBy(Locale::getCountry,toSet()));
- counting会产生收集到的元素的个数。
Map<String, Long> countryToLocaleCounts = locales.collect(
groupingBy(Locale::getCountry,counting()));
- summing(Int|Long|Double)会接受一个函数作为引元,将函数运用到下游元素中,并产生他们的和。
Map<String,Integer> stateToCityPopulation = cities.collect(
groupingBy(City::getState,summingInt(City::getPopulation)));
- maxBy和minBy会接受一个比较器,并产生下游元素中的最大值和最小值。
Map<String, Optional<String>> stateToLongestCityName = cities
.collect(groupingBy(City::getState,mapping(City::getName,
maxBy(Comparator.comparing(String::length)))));
- mapping方法会产生将函数引用到下游结果上的收集器,并将函数值传递给另一个收集器。
Map<String,Set<String>> countryToLanguages = locales.collect(
groupingBy(Locale::getDisplayCountry,mapping(
Locale::getDisplayLanguage,toSet())));
- 注意:将收集器组合起来是一种很强大的方式,但是它也会导致产生非常复杂的表达式。
package JavaSE8的流库;
import static java.util.stream.Collectors.*;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.IntSummaryStatistics;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;
public class DownstreamCollectors {
public static class City
{
private String name;
private String state;
private int population;
public City(String name,String state,int population)
{
this.name = name;
this.state = state;
this.population = population;
}
public String getName()
{
return name;
}
public String getState()
{
return state;
}
public int getPopulation()
{
return population;
}
}
public static Stream<City> readCities(String filename) throws IOException
{
return Files.lines(Paths.get(filename))
.map(l->l.split(",")).map(a->new City(a[0],a[1],Integer.parseInt(a[2])));
}
public static void main(String[] args) throws IOException {
// TODO 自动生成的方法存根
Stream<Locale> locales = Stream.of(Locale.getAvailableLocales());
//locales = Stream.of(Locale.getAvailableLocales());
Map<String,Set<Locale>> countryToLocaleSet = locales.collect(
groupingBy(Locale::getCountry,toSet()));
System.out.println("countryToLocaleSet:"+countryToLocaleSet);
locales = Stream.of(Locale.getAvailableLocales());
Map<String, Long> countryToLocaleCounts = locales.collect(
groupingBy(Locale::getCountry,counting()));
System.out.println("countryToLocaleCounts:"+countryToLocaleCounts);
Stream<City> cities = readCities("cities.txt");
Map<String,Integer> stateToCityPopulation = cities.collect(
groupingBy(City::getState,summingInt(City::getPopulation)));
System.out.println("stateToCityPopulation:"+stateToCityPopulation);
cities = readCities("cities.txt");
Map<String, Optional<String>> stateToLongestCityName = cities
.collect(groupingBy(City::getState,mapping(City::getName,
maxBy(Comparator.comparing(String::length)))));
System.out.println("stateToLongestCityName:"+stateToLongestCityName);
locales = Stream.of(Locale.getAvailableLocales());
Map<String,Set<String>> countryToLanguages = locales.collect(
groupingBy(Locale::getDisplayCountry,mapping(
Locale::getDisplayLanguage,toSet())));
System.out.println("countryToLanguages:"+countryToLanguages);
cities = readCities("cities.txt");
Map<String, IntSummaryStatistics> stateToCityPopulationSummary = cities
.collect(groupingBy(City::getState,summarizingInt(City::getPopulation)));
System.out.println("stateToCityPopulationSummary:"+stateToCityPopulationSummary);
cities = readCities("cities.txt");
Map<String,String> stateToCityNames = cities.collect(
groupingBy(City::getState,
reducing("",City::getName,(s,t)->s.length()==0?t:s+","+t)));
System.out.println("stateToCityNames:"+stateToCityNames);
cities = readCities("cities.txt");
stateToCityNames = cities.collect(groupingBy(City::getState,
mapping(City::getName, joining(","))));
System.out.println("stateToCityNames:"+stateToCityNames);
}
}
运行结果:
(如有问题,请评论!Thanks♪(・ω・)ノ)