Lambda Ausdruck mit Wildcard einschränken

Bitte aktiviere JavaScript!
Hallo zusammen,

ich hänge gerade an den Lambdas in Verbindung mit Comparatoren :-D

Hab mir eine kleine Klasse Pair geschrieben die einfach ein Pärchen speichert.
Java:
public class Pairs<T,U>  {
   
    private T t;
    private U u;
   
    public Pairs() {
        t = null;
        u = null;
    }
   
    public Pairs(T t, U u) {
        this.t=t;
        this.u=u;
    }
   
    public T getT() {
        return t;
    }
   
    public U getU() {
        return u;
    }
   
    public String toString() {
        return "("+t.toString()+" ,"+u.toString()+")";
    }
}
Nun habe ich ein Pärchen erstellt mit String und Integer :) und 2 Comparatoren mit Lambda geschrieben die nach T und nach U sortiert werden (also die Pärchen).

Java:
List<Pairs<String,Integer>> list = new ArrayList<>();
            list.add(new Pairs<String,Integer>("I",1));
            list.add(new Pairs<String,Integer>("V",5));
            list.add(new Pairs<String,Integer>("C",100));
            list.add(new Pairs<String,Integer>("II",2));
            list.add(new Pairs<String,Integer>("IX",9));
           
            Collections.sort(list, (o1,o2) -> o1.getT().compareTo(o2.getT()));
            System.out.println(list);
            Collections.sort(list, (o1,o2) -> o1.getU().compareTo(o2.getU()));
            System.out.println(list);
Doch wenn ich einen eigenen Referenztyp nehme klappt das ganze nicht mehr da ich keine compareTo Methode mehr habe.
Deswegen möchte ich den Lambda - Ausdruck über die Wildcards so zum Beispiel einschränken damit Vorausgesetzt ist das T z. B. das Interface Comparable implementiert und somit die Methode compareTo zur verfügung stellt:
Java:
Comparator<T extends Comparable<? super T>,U>
Wenn ich das ganze als eigene Klasse schreiben würde wäre es kein Problem oder als Anonyme Klasse doch als Lambda verstehe ich nicht wie das gehen soll :(

Hier einfach mal als eine eigene Klasse (inner class):
Java:
//    public static class FirstComparator<T extends Comparable<? super T>,U> implements Comparator<Pairs<T,U>> {
//
//        @Override
//        public int compare(Pairs<T,U> o1, Pairs<T,U> o2) {
//            if(o1.getT() == null)
//                return o2.getT() == null ? 0:-1;
//            if(o2.getT() == null)
//                return 1;
//            return o1.getT().compareTo(o2.getT());
//        }
//      
//    }
Vielleicht kann mir da einer weiter Helfen :) vielleicht stoßen Lambdas hier ja auch an Ihre Grenzen was echt schade wäre denn ich dachte ja dafür wären sie da für Anonyme Klassen "Leichter" und "Verständlicher" zu schreiben :D

LG
 
Du musst nicht den Typ der beiden Typparameter in der Lambda-Funktion einschränken, sondern in deinem generischen Typ `Pairs`:
Java:
public class Pairs<T extends Comparable<T>, U extends Comparable<U>>  { ... }
Denn woher soll denn die Lambda-Funktion wissen, dass es sich bei den Werten in der Pairs Instanz wirklich um Comparables handelt - bzw. wenn es sich nicht um Comparables handelt, dann kann die Lambda-Funktion ja auch nichts mehr machen als zu sagen: Ne, geht nicht. Typen sind nicht Comparable. Bei String und Integer war das gegeben, weil diese Comparable implementieren. Aber, wenn du willst, dass alle möglichen Typargumente von Pairs auch Comparable sind, dann musst du das dort angeben.
 
By the way: Der Vergleich nach getT() oder getU() lässt sich mit Hilfe von Comparator.comparing() und Method References noch etwas kompakter schreiben:
Java:
import static java.util.Collections.sort;
import static java.util.Comparator.comparing;
...
// Statt: sort(list, (o1,o2) -> o1.getT().compareTo(o2.getT()));
sort(list, comparing(Pairs::getT));
// Statt: sort(list, (o1,o2) -> o1.getU().compareTo(o2.getU()));
sort(list, comparing(Pairs::getU));
EDIT: Auch würde ich die Klasse `Pairs` in `Pair` umbenennen, denn eine Instanz dieser Klasse repräsentiert ja nicht mehrere Paare sondern genau ein Paar.
 
Danke.

Das comparing etc muss ich mir später irgendwann mal anschauen wenn ich so durchblicke :D
Also eigentlich wollte ich bei Pair das nicht einschränken.
Doch anders geht es nicht!

Der Lambda Ausdruck Funkioniert also immer sobald T implements Comparable oder? Dann könnte man bevor man die Methode aufruft doch abfragen ob T eine instanceOf von Comparable ist? Oder geht das nun auch wieder nicht? Andernfalls läuft man eben in eine Exception :D

Danke für das schnelle FeedBack :)
LG
 
Also eigentlich wollte ich bei Pair das nicht einschränken.
Doch anders geht es nicht!
Mach Dir die Sache mit dem Lambdas nicht so schwer: immer, wenn die Implementierung eines funktionalen Interfaces erwartet wird, kannst Du stattdessen einen Lambda-Ausdruck verwenden. Ausschlaggebend für die Typen ist die Spezifikation der Methode im funktionalen Interface - das ist genauso wie bei der Implementierung mit einer anonymen Klasse.
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben