[英]Mapping objects using java8
假設我有一個Foo對象列表。 我必須使用Foo上的一個屬性來從數據源獲取Bar對象。 然后,我必須將每個bar對象映射回獲得Bar的原始Foo對象。
public class Foo {
int barId;
}
public class Bar {
int barId;
}
Set<Foo> inputFoo;
Map<Bar, Foo> barToFoo;
public Bar getBar(int barId);
我的嘗試如下:
List<Bar> allBarsInFoo = inputFoos.stream()
.map(Foo::barId)
.forEach(b -> getBar(b))
我不知道如何在完成上述操作后不進行更多繁瑣和不必要的操作就獲得Bar到Foo的地圖。
編輯:使我的問題更籠統,有沒有辦法保持對原始對象的引用,在原始對象列表之外的流中執行一堆過濾器/地圖操作,然后映射過濾器/地圖的結果作為鍵,原始對象作為結果圖的值?
我認為Collectors.toMap()
是您要找的東西:
Map<Bar, Foo> barToFoo = inputFoo.stream()
.collect(Collectors.toMap(f -> getBar(f.barId), Function.identity()));
似乎您想要一個反向映射,或每個值都指向其鍵的映射。 這樣做有幾個問題,第一個問題是不能保證數學映射(有時表示為函數)是數學身份(這是說函數具有反函數的一種奇特的方式)。
因此,采用A鍵並提供B值的地圖看起來像
f(A) -> B
但是在許多地圖上,人們無法寫成逆函數,而逆函數仍然是一種函數
f'(B) -> A (only exists for some functions)
例如
f(x) = x*x
讓一個人使用輸入
f(0) = 0
f(1) = 1
f(2) = 4
並且
f(-1) = 1
f(-2) = 4
所以反函數必須要做
f'(0) = 0 (the zero's are swapped compared to the above example)
f'(1) = 1 or -1 (sorry, but that's not valid output for a function)
f'(4) = 2 or -2 (ditto)
這意味着地圖通常是不可逆的。 但是,如果將鍵入放寬為幾乎是逆的,則可以生成廣義逆:
Map<Foo, Bar> x
(back maps to)
Map<Bar, Collection<Foo>> y;
流API很不錯,但是在這種情況下,它可能無法為您提供最簡單的解決方案。
Map <Bar, Set<Foo>> backmap = new HashMap<>();
for (Map.Entry<Foo, Bar> entry : barToFoo.entrySet()) {
if (backmap.contains(entry.getValue()) {
backmap.get(entry.getValue()).add(entry.getKey());
} else {
backmap.put(entry.getValue(), new HashSet<Foo>(entry.getKey));
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.