使用lambda和流来表达代码块的简洁方法

时间:2018-08-30 21:12:43

标签: java lambda java-stream collectors

您好,我有一段代码将一种窗口对象的列表转换为另一种,并将其填充在以id为键的映射中。可能有许多具有相同ID但名称和属性不同的对象实例。我正在做的是获取列表[W1(1,2,3),W1(2,3,4),W2(1,3,4)...]并将其转换为 映射[键W1,值(1,2,3),(2,3,4)       键W2,...。    ]

这是代码段...

    List<LinWin> list = winDao.get.....

    Map<Long, List<MacWin>> res = new HashMap<>();
    for (LinWin mw : list) {

        List<MacWin> l2 = res.get(mw.getId());
        if (l2 == null) {
            l2 = new ArrayList<>();
            res.put(mw.getId(), l2);
        }
        l2.add(new MacWin(mw.getName(), mw.getVendor(), mw.isFixed()));
    }

返回资源

我想知道是否可以使用流和lambda将其折叠。

list.stream()。collect(Collectors.toMap(.....

2 个答案:

答案 0 :(得分:0)

您可以这样做

Map<Long, List<MacWin>> macWinById = list.stream()
        .collect(Collectors.groupingBy(LinWin::getId,
            Collectors.mapping(lw -> new MacWin(lw.getName(), lw.getVendor(), lw.isFixed()), 
                Collectors.toList())));

首先使用groupingBy收集器将Win实例按其ID值分组。然后进行映射,同时传递下游collector,该下游{{1}}将生成的对象收集到容器中。

答案 1 :(得分:0)

例如,如果您有一个可以从LinWin转换为MacWin的方法(可以将其设为静态,也可以为MacWin创建一个可以接受LinWin作为输入)。我将在这里生成一个静态方法:

private static MacWin of(LinWin lw){
    return new MacWin(mw.getName(), mw.getVendor(), mw.isFixed());
}

以后的用法是(我在这里不使用流,因为在这种情况下,在没有流的情况下,对我来说看起来更容易):

Map<Long, List<MacWin>> res = new HashMap<>();
mw.forEach(x -> res.computeIfAbsent(mw.getId(), y -> new ArrayList<>()).add(of(x)));