class A {
private String x;
private String y;
//getters and setters
}
假设我有一个A类型的对象列表。现在考虑。
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。
答案 0 :(得分:4)
您可以使用Java 8 Stream 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
。
答案 1 :(得分:4)
如果属性x的值相等,则将它们分组到子列表。
您自己说过,您需要按属性x
的值对列表进行分组。使用Stream API,可以使用收集器Collectors.groupingBy(classifier)
来完成。此收集器返回一个映射,其中条目是将给定分类器应用于Stream元素的结果,并将值收集到列表中。
Map<String, List<A>> map = aList.stream().collect(Collectors.groupingBy(A::getX));
此地图将包含2个条目。第一个是关键x
指向元素a
和b
;第二个是关键y
指向元素c
和d
。
答案 2 :(得分:0)
@Tagir提到了一种方法,如果我想检查两个属性值的相等性。只需发布不同即可实现它。
Map<String, Collection<List<A>>> result = aList.parallelStream()
.collect(Collectors.groupingBy(A::getX,
Collectors.collectingAndThen(Collectors.groupingBy(A::getY), Map::values)));
parallelStream()
以防万一。