2015-09-05 4 views
9

Woher weiß Java, welche String::compareTo Methodenreferenz verwendet werden soll, wenn Collections.sort(someListOfStrings, String::compareTo); aufgerufen wird? compareTo ist nicht statisch und es muss die value der "linken Seite" des Vergleichs kennen.Woher weiß Java 8, welche String :: compareTo Methodenreferenz beim Sortieren verwendet werden soll?

+0

Was ist das? String :: compareTo' –

+0

Ihre Frage ist nicht klar: 'Collections.sort' sortiert die Elemente einer Sammlung,' String :: compareTo' wird verwendet, um zwei Zeichenketten in dieser Sammlung zu vergleichen. Wenn string a alfasin

Antwort

11

Angenommen, Sie Methode Referenz für Comparator Schnittstelle verwenden:

Comparator<String> cmp = String::compareTo; 

Wenn Sie die cmp.compare(left, right) nennen (die „einzige abstrakte Methode“ oder „SAM“ von Comparator Schnittstelle ist), tritt die Magie:

int result = cmp.compare(left, right); 
          |  | 
    /------------------------/  | 
    |    /---------------/ 
    |    | 
left.compareTo(right); 

Grundsätzlich werden alle Parameter von SAM in die Parameter der referenzierten Methode konvertiert, aber this Objekt (das auf der linken Seite ist) wird auch als Parameter gezählt.

+7

Dies wird als * nicht gebundene Instanz * -Methodenreferenz bezeichnet. –

+0

@Tagir Valeev aber wie passt 'String :: compareTo's Typ' Comparator ''? Die Typensignatur stimmt nicht überein ... 'String's' compareTo' Methode ist 'public int compareTo (Zeichenkette anotherString)', 'Vergleicher ' ist 'int compare (Zeichenkette o1, Zeichenkette o2);' Ich kenne I Ich vermisse etwas, ich kann die Punkte nicht ganz verbinden. – stantonk

+2

@stantonk, denke über 'this' als über einen weiteren Parameter, so' public int compareTo (String anotherString) 'ist wie' public static int compareTo (String this, String anotherString) '. Generell funktioniert es in OOP-Sprachen intern wie folgt: Der Objektzeiger (Referenz) wird in den ersten Parameter der Funktion/Methode konvertiert. –

0

OK, die Quelle Collections.sort() sieht wie folgt aus:

public static <T> void sort(List<T> list, Comparator<? super T> c) { 
    Object[] a = list.toArray(); 
    Arrays.sort(a, (Comparator)c); 
    ListIterator i = list.listIterator(); 
    for (int j=0; j<a.length; j++) { 
     i.next(); 
     i.set(a[j]); 
    } 
} 

Ich denke, es ist jetzt ganz klar. Der Inhalt ist eine Liste. Es bedeutet, dass es eine Bestellung hat und die Artikel nacheinander in dieser Reihenfolge behandelt werden.

+0

Entschuldigung, das beantwortet meine Frage nicht. Was ich versuche zu verstehen, ist, wie Java weiß, für jedes Element in der zu sortierenden Liste die richtige 'String :: compareTo'-Methodenreferenz zu verwenden. – stantonk

+0

Also, zum Beispiel, haben Sie eine Liste "[" c "," b "," a "]'. Das erste Element in dieser Liste, "c", ist eine Instanz der Klasse "String", die eine Eigenschaft von "Wert" hat, die ein Zeichen-Array ist, das ein einzelnes Zeichen, "c", enthält. 'compareTo' macht einen Vergleich zwischen" c "und" b "tief innerhalb der" Collections.sort "-Methode, d. h." if (c.compare (a [runHi ++], a [lo]) <0) ". Ich sehe nicht, wie die Methodenreferenz Sie von "Comparable" zu "Comparator" bringt. – stantonk

Verwandte Themen