Как создать поток <String[]> с одним элементом с Stream.of?
Использование Stream.of
для создания общих потоков очень удобно, но что если я хочу создать Stream<String[]>
только из одного элемента?
Допустим, у меня есть:
String[] tropicalFruits = new String[] {"pineapple", "banana", "mango"};
String[] fruits = new String[] {"melon", "peach", "apple"};
Затем Stream.of(tropicalFruits, fruits)
создает Stream<String[]>
из двух элементов. Как я могу добиться того же для потока одного элемента? Если я попробую:
Stream<String[]> fruityStream = Stream.of(tropicalFruits);
Я получил:
Ошибка: несовместимые типы: переменная вывода T
имеет несовместимые границы
ограничения равенства: java.lang.String[]
нижние границы: java.lang.String
Stream<String[]> fruityStream = Stream.of(fruits);
^---------------^
Я гуглил это и искал в SO, но я ничего не получил. Мне кажется, что это не очень необычная или эзотерическая проблема, поэтому удивительно, что я не получил никаких ответов (или я не ищу правильные ключевые слова).
Ответы
Ответ 1
Решение
Stream<String[]> stream = Stream.<String[]>of(tropicalFruits);
или
Stream<String[]> stream = Stream.of(new String[][]{tropicalFruits});
объяснение
Чтобы создать Stream<T>
, Stream.of
принимает либо T
либо T...
Параметр T[]
отлично применяется ко второй подписи.
Поэтому передача String[]
вызывает Stream.of(String...)
.
Чтобы изменить это поведение, нам нужно предоставить дополнительную информацию о T
(1) или определить его более четко (= однозначно) (2).
Мне пришло в голову две идеи:
- Чтобы указать аргумент типа метода явно использовать первую подпись.
Stream.<String[]>of(new String[]{})
создаст Stream<String[]>
. - Для того, чтобы обернуть
T[]
значение в T[][]
массива, чтобы использовать вторую подпись.
Stream.of(new String[][]{})
создаст Stream<String[]>
.
Ответ 2
Этот Stream<String[]> fruittyStream = Stream.of(tropicalFruits);
вызывает метод var-arg Stream.of
.
Я могу подумать об этом обходном пути:
List<String> list = Arrays.asList("one");
Stream.of(list)
.map(x -> x.toArray(new String[1]));
Или вы можете вызвать метод var-args несколько иначе:
Stream.of(tropicalFruits, null)
.filter(Objects::nonNull)
.forEach(x -> System.out.println(Arrays.toString(x)));
Ответ 3
Вызывая Stream#of
с одним T[]
, Java по умолчанию использует метод vararg factory, создавая Stream<T>
а не Stream<T[]>
. Чтобы создать Stream<T[]>
с помощью одного элемента, вы можете создать Stream<T[]>
с несколькими элементами и limit(1)
вызова limit(1)
или использовать фиктивный массив для второго элемента:
Stream<String[]> stream = Stream.of(tropicalFruits, fruits).limit(1);
Stream<String[]> stream = Stream.of(tropicalFruits, new String[] {});