根据值列表中最旧的值对 TreeMap 中的键进行排序?

Ordering the Keys in a TreeMap dependant on the oldest value in its list of values?

我有一个TreeMap如下:

  TreeMap<Parent, List<Child>> mapOfParentsAndChilds = new TreeMap<Parent, List<Child>>();

我想按以下条件订购地图:

地图中的第一个键 (Parent object) 将是其列表中 最旧的 child 的键值。

即如果 Parent A 的值列表中最老的 child 是 20 岁,而 Parent B 的值列表中最老的 child值是 19 岁然后 Parent A 应该是 before Parent B 在地图上等等。

如何实施此解决方案?

Child实体:

@Entity
@Table(name = "CHILD")
public class Child
{
    //other vars 

    @Column(name = "AGE")
    private int age;

}

要创建具有自定义排序的地图,您可以使用带有 Comparator 的构造函数。比较器可让您决定如何订购密钥。

在Java 8 Comparator.comparing was added, which makes creating a comparator using the new 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)
);

请注意,children 的列表需要可以从 parent object 访问。您不能按键对应值的 属性 对地图键进行排序,因为地图值可以更改。

@assylias: If two parents have oldest children of the same age, only one will be kept in the map because they will be deemed equal.

为了解决这个问题,我们可以使用 thenComparing() 链接一个额外的比较器。如果第一个说最旧的 children 相等,则使用这个额外的比较器。您可以添加您想要决定哪个 parent 在这种情况下获胜的任何其他标准。我加入了 System::identityHashCode 作为决胜局。 identityHashCode returns 一个任意但一致的整数。本质上,我用它来确保不同的 parent 比较不相等,但哪个先出现是任意的。

如果您有更好的标准可以使用,我鼓励您更改此标准。例如,如果每个 parent 都有一个唯一的名称,.thenComparing(Parent::getName) 会更好。