繁体   English   中英

Java 8按条件收集两个列表进行映射

[英]Java 8 Collect two Lists to Map by condition

我有一个对象:

public class CurrencyItem {
    private CurrencyName name;
    private BigDecimal buy;
    private BigDecimal sale;
    private Date date;
    //...
}

其中CurrencyName是以下之一:EUR,USD,RUR等。

还有两个清单

List<CurrencyItem> currenciesByCommercialBank = ...
List<CurrencyItem> currenciesByCentralBank = ...

我该如何合并这个名单的Map<CurrencyItem, CurrencyItem>键进行currenciesByCommercialBank和值currenciesByCentralBank与条件,例如

currenciesByCommercialBank.CurrencyName == currenciesByCentralBank.CurrencyName

这应该是最佳的。 您首先要建立一个从货币到商业银行的地图。 然后你穿过你的中心建立一个从商业到中心的地图(在第一张地图中查找)。

    List<CurrencyItem> currenciesByCommercialBank = new ArrayList<>();
    List<CurrencyItem> currenciesByCentralBank = new ArrayList<>();
    // Build my lookup from CurrencyName to CommercialBank.
    Map<CurrencyName, CurrencyItem> commercials = currenciesByCommercialBank
            .stream()
            .collect(
                    Collectors.toMap(
                            // Map from currency name.
                            ci -> ci.getName(),
                            // To the commercial bank itself.
                            ci -> ci));
    Map<CurrencyItem, CurrencyItem> commercialToCentral = currenciesByCentralBank
            .stream()
            .collect(
                    Collectors.toMap(
                            // Map from the equivalent commercial
                            ci -> commercials.get(ci.getName()),
                            // To this central.
                            ci -> ci
                    ));

以下代码是O(n 2 ),但对于小型集合(您的列表可能是这样),它应该是正常的:

return currenciesByCommercialBank
    .stream()
    .map(c ->
        new AbstractMap.SimpleImmutableEntry<>(
            c, currenciesByCentralBank.stream()
                                      .filter(c2 -> c.currencyName == c2.currencyName)
                                      .findFirst()
                                      .get()))
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
  }

如果要断言以上是合适currenciesByCentralBank包含了每个项目的比赛currenciesByCommercialBank 如果两个列表可能存在不匹配,则以下内容是合适的:

currenciesByCommercialBank
    .stream()
    .flatMap(c ->
        currenciesByCentralBank.stream()
                               .filter(c2 -> c.currencyName == c2.currencyName)
                               .map(c2 -> new AbstractMap.SimpleImmutableEntry<>(c, c2)))
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

在这种情况下,地图将包含所有匹配项,并且不会抱怨缺少条目。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM