簡體   English   中英

Java 8流:對不同鍵進行求和

[英]Java 8 streams: sum values on a distinct key

我有一個包含以下列標題的行的文件:

CITY_NAME  COUNTY_NAME  POPULATION

Atascocita  Harris  65844
Austin  Travis  931820
Baytown Harris  76335
...

我正在使用流來嘗試生成類似於以下內容的輸出:

COUNTY_NAME  CITIES_IN_COUNTY  POPULATION_OF_COUNTY
Harris  2  142179
Travis  1  931820
...

到目前為止,我已經能夠使用流來獲取不同縣名的列表(因為這些是重復的),但現在我遇到的問題是在一個不同的縣獲得城市數量,從而得到城市人口總數的總和。這些縣。 我已經將文件讀入類型為texasCitiesClass的ArrayList中,我的代碼到目前為止看起來像:

public static void main(String[] args) throws FileNotFoundException, IOException {
    PrintStream output = new PrintStream(new File("output.txt"));
    ArrayList<texasCitiesClass> txcArray = new ArrayList<texasCitiesClass>();
    initTheArray(txcArray); // this method will read the input file and populate an arraylist
    System.setOut(output);

    List<String> counties;
    counties = txcArray.stream()
            .filter(distinctByKey(txc -> txc.getCounty())) // grab distinct county names
            .distinct() // redundant?
            .sorted((txc1, txc2) -> txc1.getCounty().compareTo(txc2.getCounty())); // sort alphabetically

}

public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
    Map<Object, String> seen = new ConcurrentHashMap<>();
    return t -> seen.put(keyExtractor.apply(t), "") == null;
}    

此時,我有一個包含唯一縣名稱的流。 由於sorted()運算符將返回一個新流,我如何獲得(並因此求和)各縣的人口值?

鑒於類(ctor,getter,setter省略)

class Foo {
    String name;
    String countyName;
    int pop;
}

class Aggregate {
      String name;
      int count;
      int pop;
}

您可以通過使用Collectors.toMap將它們映射到聚合對象並使用其mergeFunction合並它們來聚合您的值。 使用TreeMap,其條目按其鍵排序。

TreeMap<String, Aggregate> collect = foos.stream()
        .collect(Collectors.toMap(
                Foo::getCountyName,
                foo -> new Aggregate(foo.countyName,1,foo.pop),
                (a, b) -> new Aggregate(b.name, a.count + 1, a.pop + b.pop),
                TreeMap::new)
        );

運用

List<Foo> foos = List.of(
        new Foo("A", "Harris", 44),
        new Foo("C", "Travis  ", 99),
        new Foo("B", "Harris", 66)
);

地圖是

{Harris = Aggregate {name ='Harris',count = 2,pop = 110},Travis = Aggregate {name ='Travis',count = 1,pop = 99}}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM