Java 8 lambdas分组和映射

Java 8 lambdas分组和映射,java,java-8,java-stream,Java,Java 8,Java Stream,给定以下事务类的列表,使用Java 8 lambdas,我想获得ResultantTo的列表,每个帐户类型一个 public class Transaction { private final BigDecimal amount; private final String accountType; private final String accountNumber; } public class ResultantDTO { private final

给定以下
事务
类的
列表
,使用Java 8 lambdas,我想获得
ResultantTo的
列表
,每个帐户类型一个

public class Transaction {

    private final BigDecimal amount;
    private final String accountType;
    private final String accountNumber;

}

public class ResultantDTO {

    private final List<Transaction> transactionsForAccount;

    public ResultantDTO(List<Transaction> transactionsForAccount){
        this.transactionsForAccount = transactionsForAccount;
    }

}
如何返回一个
列表
,将列表从每个映射键传递到构造函数中,每个
accountType都包含一个
ResultantTo

static ResultantDTO from(List<Transaction> transactions) {...}
static resultdto from(列表事务){…}
你可以写:

Map<String, List<Transaction>> transactionsGroupedByAccountType = transactions
    .stream()
    .collect(groupingBy(Transaction::getAccountType));

Map<String, ResultantDTO> result = transactionsGroupedByAccountType.entrySet().stream()
         .collect(toMap(Entry::getKey, e -> from(e.getValue)));
映射事务GroupedByAccountType=事务
.stream()
.collect(分组依据(事务::getAccountType));
映射结果=TransactionGroupedByAccountType.entrySet().stream()
.collect(toMap(Entry::getKey,e->from(e.getValue));

您可以在一个流中执行此操作,但这可能更干净、更简单。

您可以使用
toMap
收集器:

Map<String, ResultantDTO> transactionsGroupedByAccountType = transactions
                .stream()
                .collect(toMap(Transaction::getAccountType,
                        t -> new ResultantDTO(t.getAmount(), 
                                              Stream.of(new SimpleEntry<>(t.getAccountNumber(), t.getAmount()))
                                                    .collect(toMap(SimpleEntry::getKey, SimpleEntry::getValue))),
                        (dt1, dt2) -> new ResultantDTO(dt1.getSumOfAmountForAccountType().add(dt2.getSumOfAmountForAccountType()), 
                                                       Stream.of(dt1.getAccountNumberToSumOfAmountForAccountNumberMap(), dt2.getAccountNumberToSumOfAmountForAccountNumberMap())
                                                             .flatMap(m -> m.entrySet().stream())
                                                             .collect(toMap(Map.Entry::getKey, Map.Entry::getValue)))));
在那里它更具可读性:

Map<String, ResultantDTO> transactionsGroupedByAccountType = transactions
                .stream()
                .collect(toMap(Transaction::getAccountType,
                               ResultantDTO::new,
                               ResultantDTO::merger));
映射事务GroupedByAccountType=事务
.stream()
.collect(toMap)(事务::getAccountType,
ResultantDTO::新建,
ResultantDTO::合并);

您可以在单流操作中执行此操作:

public List<ResultantDTO> convert(List<Transaction> transactions) {
    return transactions.stream().collect(
            collectingAndThen(
                groupingBy(
                        Transaction::getAccountType,
                        collectingAndThen(toList(), ResultantDTO::new)),
                map -> new ArrayList<>(map.values())));
}
公共列表转换(列表事务){
return transactions.stream().collect(
收集然后(
分组依据(
事务::getAccountType,
收集然后(toList(),ResultantTo::new)),
map->newarraylist(map.values());
}

这里使用了两次
collecting和
:一次用于下游
Collector
将列表转换为
ResultantDTO
对象,一次用于将结果映射转换为其值列表。

您能展示一下,如果不使用
操作,您将如何做您想要做的事情吗?
Map<String, ResultantDTO> transactionsGroupedByAccountType = transactions
                .stream()
                .collect(toMap(Transaction::getAccountType,
                               ResultantDTO::new,
                               ResultantDTO::merger));
public List<ResultantDTO> convert(List<Transaction> transactions) {
    return transactions.stream().collect(
            collectingAndThen(
                groupingBy(
                        Transaction::getAccountType,
                        collectingAndThen(toList(), ResultantDTO::new)),
                map -> new ArrayList<>(map.values())));
}