Obecnie zawsze, gdy muszę utworzyć strumień z tablicy, robię to
String[] array = {"x1", "x2"};
Arrays.asList(array).stream();
Czy istnieje bezpośredni sposób tworzenia strumienia z tablicy?
źródło
Obecnie zawsze, gdy muszę utworzyć strumień z tablicy, robię to
String[] array = {"x1", "x2"};
Arrays.asList(array).stream();
Czy istnieje bezpośredni sposób tworzenia strumienia z tablicy?
Możesz użyć Arrays.stream np
Arrays.stream(array);
Możesz także użyć, Stream.of
jak wspomniał @fge, który wygląda jak
public static<T> Stream<T> of(T... values) {
return Arrays.stream(values);
}
Ale uwaga Stream.of(intArray)
zwróci, Stream<int[]>
podczas gdy Arrays.stream(intArr)
zwróci pod IntStream
warunkiem, że przekażesz tablicę typu int[]
. Zatem w skrócie dla typów prymitywnych można zaobserwować różnicę między 2 metodami np
int[] arr = {1, 2};
Stream<int[]> arr1 = Stream.of(arr);
IntStream stream2 = Arrays.stream(arr);
Po przekazaniu tablicy pierwotnej do Arrays.stream
wywoływany jest następujący kod
public static IntStream stream(int[] array) {
return stream(array, 0, array.length);
}
a po przekazaniu tablicy pierwotnej do Stream.of
następującego kodu jest wywoływana
public static<T> Stream<T> of(T t) {
return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
}
Dlatego otrzymujesz różne wyniki.
Zaktualizowano : Jak wspomniał komentarz Stuarta Marksa Przeciążenie podzakresu Arrays.stream
jest lepsze niż używanie, Stream.of(array).skip(n).limit(m)
ponieważ pierwszy daje strumień SIZED, podczas gdy drugi nie. Powodem jest to, że limit(m)
nie wie, czy rozmiar jest m, czy mniejszy niż m, podczas Arrays.stream
gdy sprawdza zakres i zna dokładny rozmiar strumienia.Możesz odczytać kod źródłowy implementacji strumienia zwracany Arrays.stream(array,start,end)
tutaj , podczas gdy dla implementacji strumienia zwracanego przez Stream.of(array).skip().limit()
jest w ramach tej metody .
Arrays.stream
zawiera wszystkie przeciążone przypadki dla tablic pierwotnych. To znaczy,Stream.of(new int[]{1,2,3})
że da ci,Stream<int[]>
podczas gdyArrays.stream
zwróci ci to,IntStream
co prawdopodobnie jest tym, czego chcesz. Więc +1Stream.of
może dać ci kilka niespodzianek (na przykład, gdy dzwoniszArrays.asList
z prymitywną tablicą i ludzie oczekująList<Integer>
odwrotu) :-)Arrays.stream
obsługuje przesyłanie strumieniowe zakresu tablicy, coIntStream.of
nie. W przeciwieństwie do tego,Stream.of
jest to lepszy wybór, jeśli chcesz miećStream<int[]>
rozmiar1
…Arrays.stream
jest lepsze niż użycie,Stream.of(array).skip(n).limit(m)
ponieważ pierwszy daje strumień SIZED, a drugi nie. Powodem jest to, żelimit(m)
nie wie, czy rozmiar jest,m
czy mniejszy niżm
, podczasArrays.stream
gdy sprawdza zakres i zna dokładny rozmiar strumienia.Arrays.stream(array,start,end)
zwraca a,Stream
którego implementacja jest tutaj , natomiastStream.of(array).skip().limit()
zwraca a,Stream
której implementacja znajduje się w tej metodzie .Alternatywa dla rozwiązania @ sol4me:
Różnica między this i
Arrays.stream()
: ma znaczenie, jeśli twoja tablica jest typu pierwotnego. Na przykład, jeśli:gdzie
someArray
jest along[]
, zwróciLongStream
.Stream.of()
z drugiej strony zwróci aStream<long[]>
z jednym elementem.źródło
Arrays.stream()
do tego działa*Stream.of()
gdy masz doArrays.stream()
czynienia z prymitywnymi tablicami. A jeśli chodzi o tablice, które nie są rzeczywistymi obiektami, cóż, to jest Java, tak było od wersji 1.0, więc zajmij się tym; rozmyślanie nad tym nic nie pomagaArrays.stream()
nie jest to wygodne, uważam to za wygodne. Wystarczająco powiedziane.*Stream.of()
jest wygodniejszy, gdy jest fałszywy; bo to kwestia preferencji . PreferujęArrays.stream()
takie przypadki, co sprawia, że z regułyStream.of()
jest to błędne, co jest wygodniejsze (algebra Peano).Lub, jeśli masz już tablicę, możesz to zrobić
W przypadku typów pierwotnych użyj
IntStream.of
lubLongStream.of
itp.źródło
int[]
można przekazać metodę akceptującą varargs, dlaczego nieStream.of(intArray)
utworzyStream<Integer>
zamiastStream<int[]>
? Czy jest też jakieś techniczne uzasadnienie, dlaczego istnieją wyspecjalizowane klasy Stream dla prymitywów?int[]
nie jest jak inne tablice. To nie jest podklasa klasyObject[]
, ale jest to podklasa klasyObject
. Tak więc, kiedy przekazujesz go doStream.of
, jest przyjmowany jakoObject
parametr, i otrzymujesz strumieńint[]
. Jest to jeden z powodów, dla których warto mieć wyspecjalizowane klasy dla prymitywów - gdybyś nie tworzył strumieni z prymitywnych tablic, byłoby to dość bolesne. Innym powodem jest to, że specjalistyczne zajęcia są bardziej efektywne, ponieważ nie trzeba ponosićObject
narzut z boksu (konwersjaint
doInteger
, aby wyglądać jak zwykłe obiekty).int[]
jestObject
, to pasowałoby do przeciążonej metodyof(T t)
i dlatego zwracaStream<int[]>
. Czyli teoretycznie, gdyby ta metoda nie była dostępna, otrzymalibyśmyStream<Integer>
w zamian? a może skutkuje to błędem kompilacji, ponieważ nie może znaleźć pasującej metody? tj.int[]
nie można traktować jakoT...
Stream<Integer>
tego, ponieważStream.of(t ... T)
nadal pasowalibyśmy w ten sam sposób.Można to zrobić również metodą niskopoziomową z opcją równoległą:
Aktualizacja: użyj pełnej tablicy.length (nie długość - 1).
źródło
Możesz użyć Arrays.stream:
Zapewnia to typ zwracany pary na podstawie typu array wejście, jeśli jej
String []
następnie powrócićStream<String>
, jeśliint []
następnie powracaIntStream
Jeśli znasz już tablicę typów wejściowych, dobrze jest użyć konkretnej tablicy, takiej jak typ wejściowy
int[]
To zwraca Intstream.
W pierwszym przykładzie Java używa metody
overloading
do znalezienia określonej metody na podstawie typów danych wejściowych, podczas gdy w drugim znasz już typ danych wejściowych i wywołujesz określoną metodę.źródło
rzadko spotykane, ale to jest najprostsza droga
źródło