亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

這是在 java8 中使用 Nested groupby 的正確方法嗎?

這是在 java8 中使用 Nested groupby 的正確方法嗎?

開心每一天1111 2023-03-23 15:43:36
我有以下對象。class RowData{  private List<RowCell> cells;}class RowCell{  private String headerName;  private String value;}我已將以下 CSV 加載到這些對象中。Country,Gender,IncomeIND,M,23531IND,F,2331IND,M,2311SNG,M,22111HYD,F,20012我需要做什么 ?查找按國家和性別分組的平均收入。到目前為止我做了什么?List<String> criteria = Arrays.asList("Country", "Gender", "Income");List<RowData> rowDataStream = rows.stream().map(rowData -> new RowData(getMatchingCells(criteria, rowData))).collect(Collectors.toList());// group by countryMap<String, List<RowData>> collect = rowDataStream.stream().collect(groupingBy(rowData -> rowData.getRowCells().get(0).getValue()));// group everything above by gender now.Map<Map<String, List<RowData>>, List<List<RowData>>> collect1 = collect.values().stream().collect(groupingBy(rowData -> rowData.stream().collect(groupingBy(o -> o.getRowCells().get(1).getValue()))));問題這是正確的方法嗎?這似乎過于復雜。你能建議一個更好的方法嗎?
查看完整描述

3 回答

?
楊__羊羊

TA貢獻1943條經驗 獲得超7個贊

首先,您可能應該將數據加載到有意義的 DTO/POJO 中:


class Row {

    String country;

    String gender;

    int income;

    // Getters etc.

}

然后,給定 a List<Row>,您可以簡單地這樣做:


Map<String, Double> groupedByCountry = list.stream().collect(

    Collectors.groupingBy(Row::getCountry, 

    Collectors.averagingInt(Row::getIncome)

)

Map<String, Double> groupedByGender = list.stream().collect(

    Collectors.groupingBy(Row::getGender, 

    Collectors.averagingInt(Row::getIncome)

)

Map<String, Map<String, Double>> groupedByCountryAndGender = list.stream().collect(

    Collectors.groupingBy(Row::getCountry, 

    Collectors.groupingBy(Row::getGender, 

    Collectors.averagingInt(Row::getIncome)

)

對于您給出的結構(RowData帶有RowCells 的列表):


Map<String, Map<String, Double>> groupedByCountryAndGender = list.stream().collect(

    Collectors.groupingBy(r -> r.getCells().get(0).getValue(), 

    Collectors.groupingBy(r -> r.getCells().get(1).getValue(), 

    Collectors.averagingInt(r -> Integer.valueOf(r.getCells().get(2).getValue()))

)


查看完整回答
反對 回復 2023-03-23
?
紫衣仙女

TA貢獻1839條經驗 獲得超15個贊

創建一個更符合邏輯的數據分組,例如:


class RowData {

    private String country;

    private String gender;

    private double income;


    // constructor, getters, setters

}

數據包含在以下列表中:


List<RowData> rowDataList = Arrays.asList(new RowData("IND", "M", 23531), 

                new RowData("IND", "F", 2331), new RowData("IND", "M", 2331),

                new RowData("SNG", "M", 22111), new RowData("HUD", "F", 20012));

現在你可以:


Map<String, Double> dataMap = rowDataList.stream()

              .collect(Collectors.groupingBy(e -> e.getCountry() + e.getGender(), 

                       Collectors.averagingDouble(RowData::getIncome)));


查看完整回答
反對 回復 2023-03-23
?
一只甜甜圈

TA貢獻1836條經驗 獲得超5個贊

老實說,我正在看你的第二個groupBy,我不知道發生了什么。要立即按性別 + 國家/地區分組,我最好這樣:

final Map<Pair<String, String>, List<RowData>> collect = rowDataStream.stream()
  .collect(groupingBy(rowData -> Pair.of(
        rowData.getCells().get(0).getValue(),
        rowData.getCells().get(1).getValue()
  )));

Pair 只是任何兩個值的簡單容器,您可以使用 apache commons pair、vavr tuple 或創建您自己的。


查看完整回答
反對 回復 2023-03-23
  • 3 回答
  • 0 關注
  • 143 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號