Comparator pola finalne

0

Napisałem dwa comparatory do porównywania stringów.

public static void main(String[] args) {
        Comparator comparator = new MyComparator();
        Comparator comparator1 = comparator.thenComparing(new MyNextComparator());
        TreeMap<String, Integer> treeMap = new TreeMap<>(comparator1);
}

class MyComparator implements Comparator<String> {
    @Override
    public int compare(String o1, String o2) {
        String a = o1.substring(o1.length() - 1);
        String b = o2.substring(o2.length() - 1);
        return a.compareTo(b);
    }
}

class MyNextComparator implements Comparator<String>{

    @Override
    public int compare(String o1, String o2) {
        return o1.compareTo(o2);
    }
}

Mój problem jest taki że nie rozumiem jak to się dzieje że obydwa comparatory są przechowywane w obiekcie MyNextComparator castowanym na Comparator.
IntelliJ pokazuje ten obiekt jako zawierający dwa pola finalne (domyślam się że to te comparatory).

Podpowie mi ktoś o co tutaj chodzi albo co mam przeczytać żeby ogarnąć mechanizm działania tego zjawiska?

1

Przyznam że nie rozumiem o co Ci chodzi gdy piszesz:

IntelliJ pokazuje ten obiekt jako zawierający dwa pola finalne (domyślam się że to te comparatory).

Ale:

Mój problem jest taki że nie rozumiem jak to się dzieje że obydwa comparatory są przechowywane w obiekcie MyNextComparator castowanym na Comparator.

Tu nie ma żadnego castowania, MyNextComparator implementuje Comparator

0

Tu nie ma żadnego castowania, MyNextComparator implementuje Comparator

Chodziło mi o ograniczenie kontekstu poprzez przypisanie obiektu klasy MyNextComparator do pola typu Comparator, widocznie błędnie nazwałem to castowaniem.
Generalnie chodzi mi o to że nie wiem w jaki sposób obiekt ten przechowuje dwa sposoby porównywania stringa, jeden z MyComparator.compare() a drugi z MyNextComparator.compare() bo widząc strukturę tego obiektu to jakoś nie mogę sobie tego wyobrazić.

default Comparator<T> thenComparing(Comparator<? super T> other) {
        Objects.requireNonNull(other);
        return (Comparator<T> & Serializable) (c1, c2) -> {
            int res = compare(c1, c2);
            return (res != 0) ? res : other.compare(c1, c2);
        };
    }

Widać trzeba by było rozszyfrować ten kod żeby wiedzieć jak wygląda zwracany przez to Comparator.

2

Masz złożony komparator. Jeśli pierwsze porównanie da 0, czyli obiekty są równe, dopiero odpalany jest drugi. Zobacz kawałek kodu, który wkleiłeś:
return (res != 0) ? res : other.compare(c1, c2);

3
happyTaco napisał(a):

Podpowie mi ktoś o co tutaj chodzi albo co mam przeczytać żeby ogarnąć mechanizm działania tego zjawiska?

Kluczowa jest linijka Comparator comparator1 = comparator.thenComparing(new MyNextComparator()); czyli złożenie dwóch komparatorów w jeden.
BTW 9 lat w Javie programuję i nie wiedziałem że coś takiego można zrobić :(

1 użytkowników online, w tym zalogowanych: 0, gości: 1