Wie kann ich einen Stream aus einem Array erstellen?


133

Derzeit mache ich es immer dann, wenn ich einen Stream aus einem Array erstellen muss

String[] array = {"x1", "x2"};
Arrays.asList(array).stream();

Gibt es eine direkte Möglichkeit, einen Stream aus einem Array zu erstellen?

Antworten:


201

Sie können Arrays.stream verwenden, z

Arrays.stream(array);

Sie können auch Stream.ofwie von @fge erwähnt verwenden, wie es aussieht

public static<T> Stream<T> of(T... values) {
    return Arrays.stream(values);
}

Note Stream.of(intArray)wird jedoch zurückgegeben, Stream<int[]>während Arrays.stream(intArr)wird zurückgegeben, IntStreamsofern Sie ein Array vom Typ übergeben int[]. Kurz gesagt, Sie können den Unterschied zwischen zwei Methoden beobachten, z

int[] arr = {1, 2};
Stream<int[]> arr1 = Stream.of(arr);

IntStream stream2 = Arrays.stream(arr); 

Wenn Sie ein primitives Array an übergeben Arrays.stream, wird der folgende Code aufgerufen

public static IntStream stream(int[] array) {
    return stream(array, 0, array.length);
}

und wenn Sie ein primitives Array an Stream.ofden folgenden Code übergeben, wird dieser aufgerufen

 public static<T> Stream<T> of(T t) {
     return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
 }

Daher erhalten Sie unterschiedliche Ergebnisse.

Aktualisiert : Wie von Stuart Marks Kommentar erwähnt. Die Überlastung des Unterbereichs von Arrays.streamist der Verwendung vorzuziehen, Stream.of(array).skip(n).limit(m)da erstere zu einem SIZED-Stream führt, während letztere dies nicht tut. Der Grund ist, dasslimit(m) nicht bekannt ist, ob die Größe m oder kleiner als m ist, während Arrays.streamder Bereich prüft und die genaue Größe des Streams kennt. Sie können den Quellcode für die von Arrays.stream(array,start,end) hier zurückgegebene Stream-Implementierung lesen , während für die von zurückgegebene Stream-Implementierung Stream.of(array).skip().limit()is innerhalb dieser Methode .


9
Diese Antwort ist besser, da Arrays.streamalle überladenen Fälle für primitive Arrays vorliegen. Dh Stream.of(new int[]{1,2,3})ich werde dir eine geben, Stream<int[]>während du eine zurückgeben Arrays.streamwirst, IntStreamwas wahrscheinlich das ist, was du willst. Also +1
user2336315

3
@ Dima Ich denke, es ist Geschmackssache. Ich meine, in Stream.ofgewissem Sinne könnte es Ihnen einige Überraschungen Arrays.asListList<Integer>
bereiten

3
Arrays.streamunterstützt das Streaming eines Bereichs des Arrays, was IntStream.ofnicht der Fall ist. Im Gegensatz dazu Stream.ofist die bessere Wahl , wenn Sie wollen eine Stream<int[]>Größe 1...
Holger

4
@Dima Die Überlastung des Unterbereichs von Arrays.streamist der Verwendung vorzuziehen, Stream.of(array).skip(n).limit(m)da erstere zu einem SIZED-Stream führt, während letztere dies nicht tut. Der Grund dafür ist, dass limit(m)nicht bekannt ist, ob die Größe mkleiner oder kleiner ist m, während Arrays.streamder Bereich die genaue Größe des Streams überprüft und kennt.
Stuart Marks

6
Für Leser, die daran interessiert sind, dieses kleine Drama zu Ende zu bringen, wird Arrays.stream(array,start,end)a zurückgegeben, Streamdessen Implementierung hier ist , während Stream.of(array).skip().limit()a zurückgegeben wird, Streamdessen Implementierung innerhalb dieser Methode liegt .
Stuart Marks

43

Alternative zur Lösung von @ sol4me:

Stream.of(theArray)

Der Unterschied zwischen diesem und Arrays.stream(): Es macht einen Unterschied, ob Ihr Array vom primitiven Typ ist. Wenn Sie zum Beispiel Folgendes tun:

Arrays.stream(someArray)

Wo someArrayist ein long[], wird es ein zurückgeben LongStream. Stream.of()Auf der anderen Seite wird a Stream<long[]>mit einem einzelnen Element zurückgegeben.


1
@ Dima sicher, aber Arrays.stream()funktioniert auch dafür
fge

2
Nun, was Streams betrifft, Bequemlichkeit! Sie müssen nicht anrufen, *Stream.of()wenn Sie Arrays.stream()mit primitiven Arrays arbeiten. Und was Arrays betrifft, die keine realen Objekte sind, so ist dies Java. Dies ist seit 1.0 der Fall. darüber
nachzudenken

2
@Dima und so ist deins; Sie halten Arrays.stream()es für nicht bequem, ich halte es für bequem. Genug gesagt.
fge

2
@ Dima ja, ich finde dein Argument *Stream.of()bequemer, um trügerisch zu sein; weil es eine Frage der Vorlieben ist . Ich bevorzuge Arrays.stream()solche Fälle, was es in der Regel Stream.of()bequemer macht (Peano-Algebra).
fge

3
@ Dima: Es ist eine Frage der Präferenz. Die Unterschiede sind so unglaublich klein, dass es überhaupt keine Rolle spielt. Genauer gesagt: Ein Unterschied von wenigen Zeichen ist nichts . Ein zusätzlicher Import in ein Paket innerhalb der Standardbibliotheken ist nichts . Und wirklich, manuelles Erstellen eines Arrays anstelle einer Varargs-Überladung ist nichts .
Jeroen Vannevel

14
Stream.of("foo", "bar", "baz")

Wenn Sie bereits ein Array haben, können Sie dies auch tun

Stream.of(array) 

Für primitive Typen verwenden Sie IntStream.ofoder LongStream.ofetc.


Was ich nicht verstehe , ist, wenn ein int[]auf ein Verfahren weitergegeben werden varargs akzeptieren, warum nicht Stream.of(intArray)produzieren einen Stream<Integer>statt Stream<int[]>? Gibt es auch technische Gründe, warum es spezielle Stream-Klassen für Grundelemente gibt?
Asgs

1
Java-Primitive sind seltsame Tiere. int[]ist nicht wie andere Arrays. Es ist keine Unterklasse von Object[], aber es ist eine Unterklasse von Object. Wenn Sie es an übergeben Stream.of, wird es als ObjectParameter verwendet und Sie erhalten einen Stream von int[]. Dies ist einer der Gründe, spezielle Klassen für primitive Arrays zu haben. Wenn Sie keine Streams aus primitiven Arrays erstellen würden, wäre dies ziemlich schmerzhaft. Der andere Grund ist, dass spezialisierte Klassen effizienter sind, da sie keinen ObjectOverhead durch das Boxen verursachen müssen (Konvertieren intin Integer, damit es wie normale Objekte aussieht).
Dima

Ah, da int[]es eine ist Object, würde es mit der überladenen Methode übereinstimmen of(T t)und daher zurückgeben Stream<int[]>. Wenn diese Methode theoretisch nicht verfügbar wäre, hätten wir die Stream<Integer>Gegenleistung erhalten? oder führt dies möglicherweise zu einem Kompilierungsfehler, weil die passende Methode nicht gefunden werden konnte? dh int[]kann nicht behandelt werden alsT...
asgs

1
Nein, wir würden immer noch nicht so weit kommen Stream<Integer>, weil wir immer Stream.of(t ... T) noch genauso zusammenpassen würden.
Dima

0

Sie können es auch mit einer Low-Level-Methode machen, die eine parallele Option hat:

Update: Verwenden Sie die volle array.length (nicht length - 1).

/** 
 * Creates a new sequential or parallel {@code Stream} from a
 * {@code Spliterator}.
 *
 * <p>The spliterator is only traversed, split, or queried for estimated
 * size after the terminal operation of the stream pipeline commences.
 *
 * @param <T> the type of stream elements
 * @param spliterator a {@code Spliterator} describing the stream elements
 * @param parallel if {@code true} then the returned stream is a parallel
 *        stream; if {@code false} the returned stream is a sequential
 *        stream.
 * @return a new sequential or parallel {@code Stream}
 *
 * <T> Stream<T> stream(Spliterator<T> spliterator, boolean parallel)
 */

StreamSupport.stream(Arrays.spliterator(array, 0, array.length), true)

0

Sie können Arrays.stream verwenden:

Arrays.stream (Array); 

Dies stellt sicher, dass der Rückgabetyp von Dampf basierend auf Ihrem Array-Eingabetyp ist, wenn er String []dann zurückkehrt Stream<String>, wenn er int []dann zurückkehrtIntStream

Wenn Sie das Array des Eingabetyps bereits kennen, sollten Sie ein bestimmtes Array wie für den Eingabetyp verwenden int[]

 IntStream.of (Array); 

Dies gibt Intstream zurück.

Im ersten Beispiel verwendet Java eine Methode overloading, um eine bestimmte Methode basierend auf Eingabetypen zu finden, während Sie im zweiten Beispiel bereits den Eingabetyp kennen und eine bestimmte Methode aufrufen.


0

selten gesehen, aber dies ist der direkteste Weg

Stream.Builder<String> builder = Stream.builder();
for( int i = 0; i < array.length; i++ )
  builder.add( array[i] );
Stream<String> stream = builder.build();
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.