我想使用Collectors.groupingBy
按两列进行分组。
我写了以下内容:
public class TestGroupKey
{
public static void main(String... args) {
List<Item> list = Arrays.asList(
new Item(1, 1, 1),
new Item(1, 1, 2),
new Item(1, 1, 3),
new Item(1, 2, 1),
new Item(1, 2, 2),
new Item(2, 1, 1),
new Item(2, 2, 1),
new Item(2, 3, 1),
new Item(2, 4, 1),
new Item(2, 4, 2),
new Item(2, 4, 3),
new Item(2, 4, 4),
new Item(3, 1, 1),
new Item(3, 1, 2),
new Item(3, 1, 3),
new Item(3, 1, 4),
new Item(3, 2, 1),
new Item(3, 2, 2)
);
Map<CustomKey, List<Item>> tupleGrouping =
list.stream().collect(Collectors.groupingBy(item -> item.customKey));
tupleGrouping.entrySet().stream()
.forEach(entry -> {
System.out.println(entry.getKey());
});
}
public static class Item {
public int topLevelId;
public int secondLevelId;
public int itemId;
public CustomKey customKey;
public Item(int topLevelId, int secondLevelId, int itemId) {
this.topLevelId = topLevelId;
this.secondLevelId = secondLevelId;
this.itemId = itemId;
this.customKey = new CustomKey(topLevelId, secondLevelId);
}
@Override
public String toString() {
return String.format("%d%d%d", this.topLevelId, this.secondLevelId, this.itemId);
}
}
public static class CustomKey {
public int topLevelId;
public int secondLevelId;
public CustomKey(int topLevelId, int secondLevelId) {
this.topLevelId = topLevelId;
this.secondLevelId = secondLevelId;
}
@Override
public String toString() {
return String.format("%d%d", this.topLevelId, this.secondLevelId);
}
}
}
预期结果是
11
12
21
22
23
24
31
32
但是实际结果是
24
31
23
22
12
21
24
31
31
24
12
32
32
11
11
11
31
我认为
groupingBy
无法正常工作。我对
CustomKey
类的使用有什么问题?此外,嵌套的地图关键字正在工作:
Map<Integer, Map<Integer, List<Item>>> entryGrouping =
list.stream()
.collect(Collectors.groupingBy(atta1 -> atta1.topLevelId,
Collectors.groupingBy(atta2 -> atta2.secondLevelId)));
最佳答案
您的CustomKey
类不会覆盖Object
的equals
方法,因此groupingBy
仅将两个CustomKey
视为相同的对象时才认为它们相等(在您的示例中从不成立,因为您为每个CustomKey
创建了一个新的Item
实例)。
public static class CustomKey {
...
@Override
public int hashCode ()
{
// if you override equals, you should also override hashCode
}
@Override
public boolean equals (Object other)
{
if (other == this)
return true;
if (!(other instanceof CustomKey))
return false;
CustomKey okey = (CustomKey) other;
return this.topLevelId == okey.topLevelId && this.secondLevelId == okey.secondLevelId;
}
...
}