2016-01-04 82 views
1
class A { 
    private String x; 
    private String y; 
    //getters and setters 
} 

假設我有A型的對象列表現在考慮的問題。從列表中<Object>具有類似屬性創建列表<Set>

A a = new A("x","something1"); 
A b = new A("x","something2"); 
A c = new A("y","something3"); 
A d = new A("y","something4"); 

List<A> aList = new ArrayList<>(); 

`alist` contains a, b,c ,d 

我可以根據以下標準過濾列表,並創建子列表的列表:如果屬性x的值等於組他們的子列表?

所以輸出應該是類似的東西。

List<A> someList = new ArrayList<>(); //someList contains a,b 

List<A> someOtherList = new ArrayList<>(); //someOtherList contains c,d. 

最終輸出列表包含someList和someOtherList。

+2

你在找'Collectors.groupingBy'嗎?將列表中的元素按其「x」屬性進行分組,然後獲取相應的列表。 –

回答

4

您可以使用Java 8個流API和groupingBy收藏家:

Map<String, List<A>> result = aList.stream().collect(
       Collectors.groupingBy(A::getX)); 

這樣你會得到一個Map鍵進行現場x的可能值,值是對應A元素的列表。

之後,你可以提取個人名單:

List<A> someList = result.get("x"); // contains a, b 
List<A> someOtherList = result.get("y"); // contains c, d 

如果你想組由兩個或多個屬性,你可以使用Arrays.asList作爲分類:

Map<List<Object>, List<A>> result = aList.stream().collect(
       Collectors.groupingBy(a -> Arrays.asList(a.getX(), a.getY()))); 

在這裏,您將有表示爲List的複合關鍵字。

+0

假設而不是方法參考(因爲只有1屬性值相等)我想檢查兩個屬性值,那麼它是如何實現 – SparkOn

+1

@SparkOn,答案已更新。 –

+0

非常感謝@Tagir – SparkOn

4

如果屬性x的值相等,則將它們組合到一個子列表中。

你自己說,你需要按屬性值x的值對列表進行分組。使用Stream API,這是通過使用收集器Collectors.groupingBy(classifier)完成的。此收集器返回一個映射,其中條目是將給定分類器應用到Stream元素的結果,並將值收集到列表中。

Map<String, List<A>> map = aList.stream().collect(Collectors.groupingBy(A::getX)); 

此地圖在您的情況下將包含2個條目。第一個將是關鍵x指向元素ab;第二個將是關鍵y指向元素cd

+0

非常感謝@Tunaki – SparkOn

0

@Tagir提到了一種方法,如果我想檢查兩個屬性值的相等性。只是發佈一個不同的實現它。

Map<String, Collection<List<A>>> result = aList.parallelStream() 
      .collect(Collectors.groupingBy(A::getX, 
      Collectors.collectingAndThen(Collectors.groupingBy(A::getY), Map::values))); 

parallelStream()以防萬一名單很大。

相關問題