Maximal Strom mit benutzerdefinierten Komparator
Unten ist mein code, der speziell für die Verwendung benutzerdefinierter Comparator
mit max
in Java 8 Stream
.
import java.math.BigDecimal;
import java.util.*;
public class BigDecimalMax {
public static BigDecimal getBigDecimalMax(List<forTest> list) {
return list.stream()
.filter(t -> t.id % 2 == 0)
.max(forTestComparator::compare) //<-- syntax error ----------
.orElse(null);
}
public static class forTestComparator implements Comparator<forTest> {
@Override
public int compare(forTest val1, forTest val2) {
return val1.value.compareTo(val2.value);
}
}
public static void main(String[] args) {
List<forTest> lst = new ArrayList<>();
Random rn = new Random();
BigDecimalMax bdm = new BigDecimalMax();
for (int i=1; i<22; ++i) {
lst.add(bdm.new forTest(i, BigDecimal.valueOf(rn.nextLong())));
}
System.out.println(getBigDecimalMax(lst));
}
class forTest {
public int id;
public BigDecimal value;
forTest(int id, BigDecimal value) {
this.id = id;
this.value = value;
}
@Override
public String toString() {
return "forTest{" +
"id=" + id +
", value=" + value +
'}';
}
}
}
Ich bin immer ein syntax-Fehler, die auf eine Methode verweisen, die ich nicht verstehe.
Error:(15, 18) java: incompatible types: invalid method reference
cannot find symbol
symbol: method compare(BigDecimalMax.forTest, BigDecimalMax.forTest)
location: class BigDecimalMax.forTestComparator
während IntelliJ IDEA beschwert, dass Non-static method cannot be referenced from a static context
.
Was genau mache ich hier falsch?
ZUSÄTZLICHE ERKLÄRUNG (04/24/14):
- Verstehe ich jetzt den Grund für den Syntaxfehler. Danke.
- Wurde speziell
Comparator
eigentlich hier nötig?
Seit BigDecimal
implementiert Comparable
aber nicht nicht scheinen zu implementieren Comparator
( es hat CompareTo()
aber keine Compare()
) ich dachte, die benutzerdefinierte Comparator
notwendig war. Deshalb konnte ich nicht einfach Comparator.comparing(ft -> ft.value)
. Ist es ein Fehler in meiner Logik?
ft -> ft.value
zu extrahieren BigDecimal (das ist Vergleichbar) aus der ForTest, und dann passieren diese lambda-arg-Komparator.Vergleich() zum erstellen eines Komparators angesichts der Vergleichbaren Instanzen.Ich Las eigentlich
comparing
Beschreibung mehrmals, aber nur nach der Lektüre Ihre Antwort (auch mehrmals), habe ich realisiert, was es bedeutete. Also comparaing
dient als Brücke zwischen Comparator
und Comparable
, richtig?Ja, das ist ein guter Weg, es zu beschreiben. Leider sind die Dokumentation und die Generika in der Signatur sind Recht kompliziert, so dass es sehr schwer ist, zu lernen, die Nutzung nur durch das Lesen der Dokumentation. Dann sehen Sie ein Beispiel und gehen Sie "aha!" Ich hoffe.
InformationsquelleAutor PM 77-1 | 2014-04-24
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sotirios Delimanolis' Antwort zeigt, wie die Probleme zu beheben, aber ich habe ein paar Dinge hinzufügen.
Wenn Sie bereits eine Klasse, die implementiert Comparator, Sie brauchen nicht zu verwenden, eine Methode, Verweis auf seine compare () - Methode. Sie können nur übergeben Sie eine Instanz direkt, da max() übernimmt eine Referenz auf ein Komparator:
oder
Jedoch die combinator-Funktionen auf Komparator in der Regel machen es unnötig, eine Klasse, die implementiert Comparator. Zum Beispiel, Sie können loszuwerden, die
forTestComparator
Klasse vollständig und genau dies tun:oder wenn
forTest
waren die offensichtlichen getValue () - Methode, könnte man umschreiben, dass der stream max () - Aufruf wie folgt:Darüber hinaus, wenn Sie wollte
forTest
Umsetzung derComparable
- Schnittstelle, Sie könnten dies tun:und die Art der Verwendung von max() Vergleichbar ist:
Zwei Stil-Hinweise:
Ich dringend davon abgeraten, mit
orElse(null)
auf Instanzen vonOptional
. Dies ist zulässig, wenn es seinen Hauptzweck, um die Nachrüstung Nutzung der neuen Java-8-APIs in code, der erwartet von null, um anzuzeigen, die Abwesenheit eines Werts. VermeidenorElse(null)
wenn Sie möglicherweise können, da dies zwingt den Anrufer auf null prüfen. Stattdessen ersetzen Sie einen tatsächlichen Wert ersetzen eines fehlenden Wertes, oder zur Rückgabe derOptional
sich der Anrufer, so der Anrufer kann gelten, was die Politik es will.Empfehle ich das festhalten an der etablierten Java-Namenskonventionen groß geschrieben, groß-und Kleinbuchstaben-Klassennamen. Die Namen der Klassen
forTest
undforTestComparator
diesen code irgendwie schwierig, mit zu arbeiten, da Sie nicht Aussehen wie Klassennamen.InformationsquelleAutor Stuart Marks
forTestComparator#compare
ist eine Instanz-Methode. Sie benötigen eine Instanz Methode Referenz, im Gegensatz zu einemstatic
Methode Referenz, die Sie haben.Etwas wie
oder der lange Weg (Ihre Klasse nicht Instanz Staat, so dass Sie nicht wirklich über die Referenz)
Finden Sie in der Java-tutorial auf Methode verweisen hier.
Seite beachten, dies
löst in einem
forTest
Wert. Sie müssen ändern Sie den Rückgabetyp der Methode.Ein besonderer Dank für die Anmerkung. Ich habe nicht realisiert seine Bedeutung auf den ersten.
InformationsquelleAutor Sotirios Delimanolis