简体   繁体   中英

TreeMap Comparator not giving the order expected?

I am attempting to create a TreeMap with the following Format:

TreeMap<Kenel, List<Dog>> treeMapOfKennelsAndDogs;

Each entry is a Kennel object with an attached list of Dogs . I want to compare each Kennel by the oldest Dog in each and order accordingly.

However the order of the treeMap is not what I am expecting, it seems that when a Kennel has a Dog List of size 1 in the list then the ordering is incorrect.

Below is my code to find the oldest Dog related to each Kennel, and also my comparator logic.

@Entity
@Table(name = "KENNEL")
public class Kennel {

    //other fields 

    @OneToMany(cascade = CascadeType.MERGE, orphanRemoval = true)
    @JoinColumn(name = "KENNEL_ID", referencedColumnName = "ID", updatable = true, insertable = true)
    private List<Dog> dogList;

     public DateTime getOldestDogInList() {
        if (dogList.size() == 0) {
            return null; }

        Dog dog= dogList.get(0);
        for (int i = 1; i < dogList.size(); i++) {
            dog d = dogList.get(i);
            if (d.getCreated().isBefore(dog.getCreated())) {
                dog = d;
            }
        }
        return dog.getCreated();
    }

Comparator logic in service class:

    Comparator<Kennel> oldestDog = new Comparator<Kennel>() {
        @Override
        public int compare(Kennel k1, Kennel k2) {

            int result = k1.getOldestDogInList().compareTo(k2.getOldestDogInList());

            return result;
        }
    };

  TreeMap<Kennel, List<Dog>> treeMapOfKennelsAndDogs = new TreeMap<>(oldestDog);    

Is there an error in code that would cause the incorrect ordering in the TreeMap?

Comparator logic in service class:

TreeSet don't know about your service classes. It knows only about Generic type inside.

1st sollution:

Comparator logic should be in a class that will be sorted in TreeSet . You should implement Comparator and ovverade compare method in Kennel class.

2nd sollution:

Set Comparator when create TreeMap .

TreeMap<Kenel, List<Dog>> treemap = new TreeMap<Kenel, List<Dog>>(new Comparator<Kenel>() {
    public int compare(Kennel k1, Kennel k2) {
        int result = k1.getOldestDogInList().compareTo(k2.getOldestDogInList());
        return result;
    }
});

Related question: What is the difference between compare() and compareTo()?

  1. Compare logic of Map<K, V> keys should not depend on V class.
  2. Do you modify keys instances after inserting in Map ? If yes - it is a problem. Equality check is only on insetion*.
  3. The ordering maintained by a tree map, like any sorted map, and whether or not an explicit comparator is provided, must be consistent with equals. (From javadoc)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM