Erklären Sie, wie dieser lambda-Ausdruck zugewiesen werden kann, um eine Iterierbar

Stieß ich auf einen cleveren code zu konvertieren, wird ein Iterator auf einen Stream von Karol auf dieser Beitrag. Ich muss zugeben, dass ich nicht vollständig verstehen, wie die lambda darf zugewiesen werden, um die Iterable geben Sie den folgenden code…

static <T> Stream<T> iteratorToFiniteStream(final Iterator<T> iterator) {
    final Iterable<T> iterable = () -> iterator;
    return StreamSupport.stream(iterable.spliterator(), false);
}

Habe ich mich dazu entschlossen meinen eigenen kleinen test, um sicherzustellen, dass es kompiliert und ausgeführt, und es funktioniert.

public void printsStream_givenIterator()
{
    Iterator<String> iterator = Arrays.asList("a", "b", "c").iterator();
    final Iterable<String> iterable = () -> iterator;
    StreamSupport.stream(iterable.spliterator(), false).forEach(s -> System.out.println(s));
}

//prints: abc

Mein Verständnis ist, dass die lambda – () -> iterator als Lieferant Funktion.

Durchsuchbar nicht FunctionalInterface also, wie kann es zugeordnet werden diese lambda?

  • Es ist das selbe wie: oracle.com/webfolder/technetwork/tutorials/obe/java/… was weist einen lambda-Ausdruck ausgeführt. Es ist hier erklärt: oracle.com/webfolder/technetwork/tutorials/obe/java/…
  • die Anmerkung ist nicht erforderlich, auf den letzten link, den Sie zur Verfügung gestellt haben: „Aber der compiler behandeln einer Oberfläche der Erfüllung der definition einer funktionalen Schnittstelle als eine funktionale Schnittstelle unabhängig davon, ob oder nicht ein FunctionalInterface annotation vorhanden ist auf der interface-Deklaration.“
InformationsquelleAutor Brad | 2017-01-25



2 Replies
  1. 8

    () -> iterator ist nicht „als ein Supplier – Funktion“. Lambda-Ausdrücke können zugewiesen werden, kongruent funktionale Schnittstelle geben. Und es ist keine Voraussetzung für eine funktionale Oberfläche zu werden, versehen mit @FunctionalInterface. Sie können eine Iterable mit einer lambda-expression, die Umsetzung der Iterable.iterator() – Methode, die nur abstract – Methode der Schnittstelle. Aber die Umsetzung von it-durch Rücksendung der gleichen Iterator Instanz jeder Zeit kann gegen die Erwartung, in der Lage zu Durchlaufen dieses Objekt mehrere Male (das ist der Grund, warum Stream nicht implementiert Durchsuchbar trotz einer iterator() – Methode).

    Diese Lösung funktioniert in diesem engen Zusammenhang, aber nicht clever.

    Die Sequenz

    final Iterable<T> iterable = () -> iterator;  iterable.spliterator()

    nur führt einen zusätzlichen Schritt, bevor Spliterators.spliteratorUnknownSize(iterator, 0) ist wie der default Methode der Iterable.spliterator() umgesetzt wird.

    So

    static <T> Stream<T> iteratorToFiniteStream(final Iterator<T> iterator) {
        final Iterable<T> iterable = () -> iterator;
        return StreamSupport.stream(iterable.spliterator(), false);
    }

    ist nur eine weniger effiziente Variante der

    static <T> Stream<T> iteratorToFiniteStream(final Iterator<T> iterator) {
        return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false);
    }

    Wenn Sie vergleichen diese, um die akzeptierten Antworten der Q&A, die du verlinkt hast, wirst du sehen, dass es genau das ist, aber die Antwort dauert, die Möglichkeit der Weitergabe von spezifischen characteristics statt 0.

    • Vielen Dank für die Zeit nehmen, um mir eine gut durchdachte und ausführliche Antwort
  2. 5

    Wie haben Sie darauf hingewiesen, die Zuordnung von ein lambda-Ausdruck ist nur dann gültig, wenn das Ziel ist eine funktionale Schnittstelle. Dies ist beschrieben in Abschnitt 15.27.3 der JLS: Typ eines Lambda-Ausdrucks.

    Einen lambda-Ausdruck ist kompatibel in einer Zuordnung Kontext -, Aufruf-Kontext, oder casting Zusammenhang mit einer Ziel-Typ T, wenn T ist eine funktionale Schnittstelle geben (§9.8) und der Ausdruck ist kongruent mit der Funktion Typ des Bodens Zieltyp abgeleitet aus T.

    Springen zu Abschnitt 9.8: Funktionelle Grenzflächen, können wir sehen, die definition einer funktionalen Schnittstelle.

    Ein funktionales interface ist ein interface mit nur einer abstrakten Methode (abgesehen von den Methoden des Objekts), und stellt somit eine einzelne Funktion Vertrag.

    Durchsuchbar nicht die Kriterien für eine funktionale Oberfläche, weil es nur eine abstrakte Methode: iterator(). (Die 2 zusätzlichen default Methoden nicht gegen die Kriterien, da Sie nicht Abstrakt sind.) Daher die Zuordnung gültig ist.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.