2016-01-04 55 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()以防万一名单很大。

相关问题