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

孤者浪人 提交于 2019-12-12 06:48:48

问题


I have a TreeMap as follows:

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

I want to order the Map by the following condition:

The First key (Parent object) in the Map will be the one that has the oldest child in their list of values.

i.e. If the oldest child in Parent A's list of values was 20 years old, and the oldest child in Parent B's list of values was 19 years old then Parent A should be before Parent B in the map and so on.

How can I implement this solution?

Child entity:

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

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

}

回答1:


To create a map with custom sorting you can use the constructor which takes a Comparator. A comparator lets you decide how to order keys.

In Java 8 Comparator.comparing was added, which makes creating a comparator using the new streaming feature easy. If you're not familiar with Java 8 streams, read up on them. They're incredibly powerful and convenient.

Map<Parent, List<Children>> mapOfParentsAndChildren = new TreeMap<>(
    Comparator.comparing(parent ->
        parent.getChildren().stream()
            .mapToInt(Child::getAge)
            .min().orElse(0)
    )
    .thenComparing(System::identityHashCode)
);

Notice that the list of children needs to be accessible from the parent object. You can't order a map's keys by a property of the keys' corresponding values because map values can change.

@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.

To fix that, we can chain an additional comparator using thenComparing(). This extra comparator is used if the first one says the oldest children are equal. You can add in whatever additional criteria you want to decide which parent wins in that case. I threw in System::identityHashCode as a tie breaker. identityHashCode returns an arbitrary, yet consistent integer. In essence I'm using it to ensure different parents compare unequal, but which one goes first is arbitrary.

If you have some better criterion to use, I encourage you to change this. For instance, if each parent has a unique name, .thenComparing(Parent::getName) would be better.



来源:https://stackoverflow.com/questions/36742915/ordering-the-keys-in-a-treemap-dependant-on-the-oldest-value-in-its-list-of-valu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!