2016-03-29 3 views
0

Wenn mit Transformationen zu tun (zB: Transformation List<People> people-List<Integer> ages, wo People eine Klasse, die eine Eigenschaft age enthält), in der Regel gibt es 2 Möglichkeiten (für mich), dies zu tun:kann ich java8 (stream, lambda) und guava kombinieren?

  1. Verwendung java8:

    people.stream().map(p -> p.getAge()).collect(toList());

  2. oder Benutzer guava2:

    Lists2.transform(people, People2AgeTransformer.INSTANCE); wo die People2AgeTransformer ist ein Transformator, der die Funktion Schnittstelle implementiert das Alter zurückzukehren.

Vor kurzem fand ich accidentlly dass java8 und Guave und der Code kann daher kombiniert werden:

Lists2.transform(people, p->p.getAge()); 

dieses Stück Code entspricht und läuft OK ohne Fehler, was mich verwirrt. Das Verfahren Lists2.transform() erfordert die zweite args die Umsetzung der Schnittstelle com.google.common.base.Function zu sein, während das java8 Lambda java.util.function.Function tatsächlich die Umsetzung der Schnittstelle ist. (Na ja, sie beide erklären, ein Verfahren B apply(A input) A nach B zu transformieren)

I don verstehe nicht, warum das funktionieren würde, da sie zwei unterschiedliche Schnittstellen verschiedener Pakete sind.

Antwort

8

die java8 Lambda ist eigentlich die Umsetzung der Schnittstelle java.util.function.Function

Nein, es ist nicht. p -> p.getAge() hat keinen vordefinierten Typ - sein Typ ist erschlossen zur Kompilierzeit abhängig von dem Kontext, in dem es aufgerufen wird. Jede funktionierende Schnittstelle, die eine int/Integer getAge(Person p) Methode hat, funktioniert.

Also beide java.util.Function<Person, Integer> und com.google.common.base.Function<Person, Integer> sind kompatibel.

+0

Vielen Dank! Ich denke, ich muss in die java8-Dokumente schauen. – LaiyuXuan

1

Wenn Sie eine Funktion zugewiesen Variable oder über Parameter übergeben, es ist wirklich einfach, sie über Java-8-Methode Referenzen anzupassen:

java.util.function.Function<Person, Integer> javaFunction = p -> p.getAge(); 
com.google.common.base.Function<Person, Integer> guavaFunction = javaFunction::apply; 
java.util.function.Function<Person, Integer> javaFunction2 = guavaFunction::apply; 

Also, wenn Sie bereits Java 8 Function Objekt in der Variablen fn haben und müssen Sie es in einen Guava-Code eingeben, verwenden Sie einfach fn::apply. Wenn Sie Java 8 Predicate in Variable pred haben, verwenden Sie pred::test, wenn Sie es in Guava-Code übergeben. Ähnliche Methodenreferenzen könnten für andere funktionale Schnittstellen verwendet werden.