2017-10-17 11 views
0

我有一個類如何根據對象中的一個變量找到列表中的常用條目?

public class A{ 
    private String x; 
    private String y; 
    private String z; 
} 

我有多個列表List<List<A>>和需要找到所有列表的共同項目。如果一個對象的x ==另一個對象的x,條目是相同的。

如果我正在檢查對象的相等性,我可以將列表轉換成集合並使用retainAll()。但是,如果y和z可以不同,那麼x怎麼做呢?x必須是相同的。

+0

不知道我是否正確,但似乎你只需要覆蓋等於和你的類A的哈希碼,所以它只有在這個返回true == x –

+0

構造一個'Map >'。迭代列表列表中的所有「A」,並將其中的每一個添加到與'A'成員'x'關聯的'Map'值中。完成後,您的地圖將爲所有「A」中的每個不同的'x'都有一個條目,並且該條目將具有所有具有該「x」的'A'的列表的值。 。 –

+0

如果你真的想要基於對象標識('==')而不是等號('equals()')匹配,那麼選擇'IdentityHashMap'作爲你的映射實現。 –

回答

0

在你的類,寫一個函數,讓你回你的X值....

public class A { 
    private String x; 
    private String y; 
    private String z; 
    ... 
    public String getX() { 
     return x; 
    } 
} 

...然後遍歷列表的-列表(爲O(n^2))和根據其共同的X值對它們進行排序。

public Map<String, List<A>> findCommonEntries(List<List<A>> aListList) { 
    Map<String, List<A>> aMap = new HashMap<>(); 

    for (List<A> aList : aListList) { 
     for (A a : aList) { 
      if (!aMap.containsKey(a.getX())) 
       aMap.put(a.getX(), new ArrayList<>()); 

      aMap.get(a.getX()).add(a); 
     } 
    } 
} 

你應該在本月底,有地圖的任意位置存儲在X到A的所有包含X.

2

這個問題的一個列表中的所有字符串是一個很好的用例的Java8流,您可以在其中應用不同的收集器來累積流的元素。下面的代碼將執行請求的轉換:

Map<String, List<A>> collect = lists.stream() 
     .flatMap(Collection::stream) 
     .collect(Collectors.groupingBy(A::getX)); 

這個API肯定是在可讀性的收益,但也可能提供良好的性能,因爲這收藏家是由JDK提供的。

您可以在這裏找到工作的例子:https://gist.github.com/sermojohn/e8828288172d5c9e85046c4b25a7d425

0

你可以扁平化全名單成一個單獨的列表,組x領域的所有元素,然後離開這個存在於所有的列表(按價值大小)鍵:

public static Set<String> getCommonEntries(List<List<A>> lists) { 
    Map<String, List<A>> map = lists.stream() 
            .flatMap(Collection::stream) 
            .collect(Collectors.groupingBy(A::getX)); 
    map.values().removeIf(l -> l.size() != lists.size()); 
    return map.keySet(); 
} 
相關問題