Преобразуване между поток и масив в Java

1. Въведение

Обикновено е необходимо да конвертирате различни динамични структури от данни в масиви.

В този урок ще демонстрираме как да преобразуваме поток в масив и обратно в Java.

2. Преобразуване на поток в масив

2.1. Справка за метода

Най-добрият начин за конвертиране на живо в масив е да се използва поток " и toArray () метод:

public String[] usingMethodReference(Stream stringStream) { return stringStream.toArray(String[]::new); }

Сега можем лесно да проверим дали преобразуването е било успешно:

Stream stringStream = Stream.of("baeldung", "convert", "to", "string", "array"); assertArrayEquals(new String[] { "baeldung", "convert", "to", "string", "array" }, usingMethodReference(stringStream));

2.2. Ламбда израз

Друг еквивалент е да се предаде ламбда израз на метода toArray ():

public static String[] usingLambda(Stream stringStream) { return stringStream.toArray(size -> new String[size]); }

Това би ни дало същия резултат, както при използването на референтния метод.

2.3. Персонализиран клас

Или можем да излезем и да създадем пълен клас.

Както можем да видим от документацията на Stream , тя приема IntFunction като аргумент. Той приема размера на масива като вход и връща масив с този размер.

Разбира се, IntFunction е интерфейс, за да можем да го приложим:

class MyArrayFunction implements IntFunction { @Override public String[] apply(int size) { return new String[size]; } };

След това можем да конструираме и използваме както обикновено:

public String[] usingCustomClass(Stream stringStream) { return stringStream.toArray(new MyArrayFunction()); }

Следователно можем да направим същото твърдение като по-рано.

2.4. Примитивни масиви

В предишните раздели разгледахме как да конвертираме String Stream в String масив. Всъщност можем да извършим преобразуването по този начин за всеки обект и той ще изглежда много подобно на примерите за String по-горе.

За примитивите обаче е малко по-различно. Ако имаме поток от цели числа , които искаме да конвертираме например в int [] , първо трябва да извикаме метода mapToInt () :

public int[] intStreamToPrimitiveIntArray(Stream integerStream) { return integerStream.mapToInt(i -> i).toArray(); }

На разположение са и методите mapToLong () и mapToDouble () . Също така, моля, обърнете внимание, че този път не предадохме никакъв аргумент на toArray () .

И накрая, нека да направим твърдението за равенство и да потвърдим, че имаме правилно нашия масив int :

Stream integerStream = IntStream.rangeClosed(1, 7).boxed(); assertArrayEquals(new int[]{1, 2, 3, 4, 5, 6, 7}, intStreamToPrimitiveIntArray(integerStream));

Ами ако все пак трябва да направим обратното? Нека да разгледаме.

3. Преобразуване на масив в поток

Можем, разбира се, да отидем и по другия път. И Java има някои специални методи за това.

3.1. Масив от обект s

Можем да я превърне в масива на поток използване Arrays.stream () или Stream.of () методи :

public Stream stringArrayToStreamUsingArraysStream(String[] stringArray) { return Arrays.stream(stringArray); } public Stream stringArrayToStreamUsingStreamOf(String[] stringArray) { return Stream.of(stringArray); }

Трябва да отбележим, че и в двата случая нашият поток е едновременно с нашия масив.

3.2. Масив от примитиви

По същия начин можем да преобразуваме масив от примитиви:

public IntStream primitiveIntArrayToStreamUsingArraysStream(int[] intArray) { return Arrays.stream(intArray); } public Stream primitiveIntArrayToStreamUsingStreamOf(int[] intArray) { return Stream.of(intArray); }

Но за разлика от преобразуването на масивите на Object , има важна разлика. При преобразуване на примитивен масив Arrays.stream () връща IntStream , докато Stream.of () връща Stream .

3.3. Arrays.stream срещу Stream.of

In order to understand the differences mentioned in earlier sections, we'll take a look at the implementation of the corresponding methods.

Let's first take a peek at Java's implementation of these two methods:

public  Stream stream(T[] array) { return stream(array, 0, array.length); } public  Stream of(T... values) { return Arrays.stream(values); }

We can see that Stream.of() is actually calling Arrays.stream() internally and that's obviously the reason why we get the same results.

Now, we'll check out the methods in the case when we want to convert an array of primitives:

public IntStream stream(int[] array) { return stream(array, 0, array.length); } public  Stream of(T t) { return StreamSupport.stream(new Streams.StreamBuilderImpl(t), false); }

This time, Stream.of() is not calling the Arrays.stream().

4. Conclusion

В тази статия видяхме как можем да конвертираме Stream s в масиви в Java и обратно. Също така обяснихме защо получаваме различни резултати при преобразуване на масив от Object s и когато използваме масив от примитиви.

Както винаги, пълен изходен код може да бъде намерен в GitHub.