我有以下对象。

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


问题


这是正确的方法吗?
似乎过于复杂。您能建议一个更好的方法吗?

最佳答案

首先,您可能应该将数据加载到有意义的DTO / POJO中:

class Row {
    String country;
    String gender;
    int income;
    // Getters etc.
}


然后,给定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)
)


对于给定的结构(带有RowDataRowCell列表):

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

10-06 14:52