Ich habe ein Traversable, und ich möchte es zu einem Java Iterator machen. Mein Problem ist, dass ich will, dass alles faul gemacht wird. Wenn ich .toIterator auf dem Traversable mache, erzeugt es eifrig das Ergebnis, kopiert es in eine Liste und gibt einen Iterator über die Liste zurück.
Ich bin mir sicher, ich vermisse hier etwas Einfaches ...
Hier ist ein kleiner Testfall, der zeigt, was ich meine:
%Vor% Der Grund, warum Sie keinen Iterator von einem Traversable bekommen können, ist, dass Sie das nicht können. Traversable definiert foreach
und foreach
durchläuft alles ohne anzuhalten. Keine Faulheit dort.
Sie haben also zwei Möglichkeiten, beide schrecklich, um es faul zu machen.
Erstens können Sie jedes Mal die ganze Sache durchlaufen. (Ich werde den Scala Iterator verwenden, aber der Java Iterator ist im Grunde der gleiche.)
%Vor% Wenn Sie effizient indizierten Slicing haben, wird dies in Ordnung sein. Wenn nicht, wird jede "nächste" Zeit in der Länge des Iterators linear sein, für O(n^2)
-Zeit nur, um sie zu durchlaufen. Aber das ist auch nicht unbedingt faul; Wenn Sie darauf bestehen, dass es sein muss, müssen Sie O(n^2)
in allen Fällen erzwingen und tun
Das ist eindeutig eine schreckliche Idee für allgemeinen Code.
Der andere Weg ist es, einen Faden zu benutzen und die Traversierung von foreach zu blockieren. Das ist richtig, Sie müssen Inter-Thread-Kommunikation für jeden einzelnen Elementzugriff durchführen! Mal sehen, wie das geht - ich werde hier Java-Threads verwenden, da Scala mitten im Wechsel zu Schauspielern im Akka-Stil steht (obwohl jeder der alten Schauspieler oder die Akka-Schauspieler oder die Scalaz-Schauspieler oder die Lift-Schauspieler oder (usw.) wird funktionieren)
%Vor% Dies vermeidet das O(n^2)
Desaster, bindet jedoch einen Thread und hat einen verzweifelten langsamen elementweisen Zugriff. Ich bekomme ungefähr zwei Millionen Zugriffe pro Sekunde auf meiner Maschine, verglichen mit & gt; 100M für eine typische Verfahrbarkeit. Dies ist eindeutig eine schreckliche Idee für allgemeinen Code.
Also da hast du es. Traversable ist im Allgemeinen nicht faul, und es gibt keinen guten Weg, es faul zu machen, ohne die Leistung enorm zu beeinträchtigen.
Ich habe dieses Problem vor kennen gelernt und soweit ich das beurteilen kann , niemand ist besonders daran interessiert, es einfacher zu machen, ein Iterator
zu erhalten, wenn alles, was Sie definiert haben, foreach
ist.
Aber wie Sie bemerkt haben, ist toStream
das Problem, also können Sie das einfach überschreiben:
Eine andere Alternative wäre, ein Iterable
anstelle von Traversable
zu definieren, und dann erhalten Sie direkt die iterator
-Methode. Könntest du ein bisschen mehr erklären, was dein Traversable
in deinem echten Anwendungsfall macht?
Tags und Links scala scala-java-interop scala-collections