我有TreeMap
如下:
TreeMap<Parent, List<Child>> mapOfParentsAndChilds = new TreeMap<Parent, List<Child>>();
我想通过以下条件订购地图:
Map中的第一个键(父对象)将是其值列表中具有最长子项的键。
即。如果父A的值列表中年龄最大的孩子 20 岁,并且父B的值列表中最大的孩子 19 年旧的那么父A应该在之前地图中的父B,依此类推。
如何实施此解决方案?
子实体:
@Entity
@Table(name = "CHILD")
public class Child
{
//other vars
@Column(name = "AGE")
private int age;
}
答案 0 :(得分:3)
要使用自定义排序创建地图,您可以使用带Comparator
的构造函数。比较器可让您决定如何订购密钥。
在Java 8中添加了Comparator.comparing
,这使得使用新的streaming功能轻松创建比较器。如果您不熟悉Java 8流,请阅读它们。他们非常强大和方便。
Map<Parent, List<Children>> mapOfParentsAndChildren = new TreeMap<>(
Comparator.comparing(parent ->
parent.getChildren().stream()
.mapToInt(Child::getAge)
.min().orElse(0)
)
.thenComparing(System::identityHashCode)
);
请注意,需要从父对象访问子项列表。您无法通过按键的属性来订购地图的密钥&#39;相应的值,因为地图值可以更改。
@assylias:如果两个父母的孩子年龄相同,那么只有一个孩子会被保留在地图上,因为他们会被认为是平等的。
为了解决这个问题,我们可以使用thenComparing()
链接一个额外的比较器。如果第一个说最大的孩子是平等的,则使用这个额外的比较器。您可以添加任何其他标准,以决定在这种情况下哪个父获胜。我投入System::identityHashCode
作为平局。 identityHashCode
返回一个任意但一致的整数。从本质上讲,我使用它来确保不同的父母比较不平等,但首先出现的是任意的。
如果您有更好的使用标准,我建议您更改此标准。例如,如果每个父母都有一个唯一的名称,.thenComparing(Parent::getName)
会更好。