在TreeMap中排序键取决于其值列表中最旧的值?

时间:2016-04-20 11:51:22

标签: java collections treemap

我有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;

}

1 个答案:

答案 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)会更好。