1

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?

java123999
  • 6,974
  • 36
  • 77
  • 121
  • If a `Kenel` already contains a `List` member, why do you need a `TreeMap>`? You can use a `TreeSet` instead. – Eran Aug 22 '16 at 10:16
  • 1
    What is the actual sorting? – Rudziankoŭ Aug 22 '16 at 10:17
  • Kennels that have dogs that are younger than others are actually earlier in the Map? – java123999 Aug 22 '16 at 10:18
  • That makes sense, because when you compare the dates, the earliest comes first. – jr593 Aug 22 '16 at 10:20
  • I don't know what you mean? surely the oldest should be first in the treemap? – java123999 Aug 22 '16 at 10:21
  • Just because x’s oldest dog is older than y’s doesn’t preclude that x could also have dogs younger than y’s. That’s no contradiction. The lists don’t have a total order, i.e. sorting them by youngest dog can lead to an entirely different order than sorting them by oldest. – Holger Sep 06 '16 at 13:15

2 Answers2

0

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()?

Community
  • 1
  • 1
Rudziankoŭ
  • 10,681
  • 20
  • 92
  • 192
  • I cannot alter this Kennel class as it is legacy code. This is why I am taking the approach that I am currently? – java123999 Aug 22 '16 at 10:43
  • @java123999, make `Adapter pattern`: create new class that extends `Kennel`, implements `Comparator`. You will not succeed in your TreeMap autosorting without doing implementing `Comparator` – Rudziankoŭ Aug 22 '16 at 10:48
  • @java123999, I edited my question. I added solution with setting `Comparator` dynamically – Rudziankoŭ Aug 22 '16 at 10:57
0
  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)
Sergei Rybalkin
  • 3,337
  • 1
  • 14
  • 27