首页 > 解决方案 > 这是在 java8 中使用嵌套 groupby 的正确方法吗?

问题描述

我有以下对象。

class RowData
{
  private List<RowCell> cells;
}

class RowCell
{
  private String headerName;
  private String value;
}

我已将以下 CSV 加载到这些对象中。

Country,Gender,Income
IND,M,23531
IND,F,2331
IND,M,2311
SNG,M,22111
HYD,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 country
Map<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()))));

问题

  1. 这是正确的方法吗?
  2. 它似乎过于复杂。你能建议一个更好的方法吗?

标签: javalambdajava-8java-stream

解决方案


创建更合乎逻辑的数据分组,例如:

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)));

推荐阅读