Java 8 收集两个列表以按条件映射
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31855403/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java 8 Collect two Lists to Map by condition
提问by marknorkin
I have an object:
我有一个对象:
public class CurrencyItem {
private CurrencyName name;
private BigDecimal buy;
private BigDecimal sale;
private Date date;
//...
}
where CurrencyName
is one of: EUR, USD, RUR etc.
其中CurrencyName
之一是:EUR、USD、RUR 等。
And two lists
和两个清单
List<CurrencyItem> currenciesByCommercialBank = ...
List<CurrencyItem> currenciesByCentralBank = ...
How can I merge this lists to the Map<CurrencyItem, CurrencyItem>
where keys are currenciesByCommercialBank
and values are currenciesByCentralBank
with condition such as
如何将此列表合并到Map<CurrencyItem, CurrencyItem>
键所在位置currenciesByCommercialBank
和值所在currenciesByCentralBank
的条件,例如
currenciesByCommercialBank.CurrencyName == currenciesByCentralBank.CurrencyName
采纳答案by OldCurmudgeon
This should be optimal. You first build a map from the currencies to their commercial banks. Then you run through your centrals building a map from commercial to central (looked up in the first map).
这应该是最佳的。您首先构建一张从货币到其商业银行的地图。然后你运行你的中心构建一张从商业到中心的地图(在第一张地图中查找)。
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
));
回答by Marko Topolnik
The following code is O(n2), but it should be OK for small collections (which your lists probably are):
以下代码是 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));
}
The above is appropriate if you want to assert that currenciesByCentralBank
contains a match for each item in currenciesByCommercialBank
. If the two lists can have mismatches, then the following would be appropriate:
如果您想断言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));
In this case the map will contain all the matches and won't complain about missing entries.
在这种情况下,地图将包含所有匹配项,并且不会抱怨缺少条目。