Например, у меня есть класс:
public class Period {
private Integer from;
private Integer to;
}
И есть список объектов в формате JSON:
[
{
"from": 1,
"to": 2
}, {
"from": 3,
"to": 4
}, {
"from": 5,
"to": 6
}
]
Я хочу собрать из List<Period> periods
все значения из этих двух полей в одну коллекцию. В моем случае это будет List<Integer> values
. Есть ли возможность использовать stream
в списке periods
? Я пытался сделать что-то вроде этого:
values = periods
.stream()
.mapToInt(p -> p.getFrom())
.boxed()
.collect(Collectors.toList());
values.addAll(
periods
.stream()
.mapToInt(p -> p.getTo())
.boxed()
.collect(Collectors.toList()));
Результат этой операции с предыдущим JSON:
[1,2,3,4,5,6]
Есть ли какой-либо другой вариант управления потоком для достижения того же результата?
Поток по периодам, для каждого элемента создайте новый поток обоих атрибутов и сгладьте их.
periods.stream()
.flatMap(p -> Stream.of(p.getTo(), p.getFrom()))
.collect(Collectors.toList());
Вы можете сделать это следующим образом:
List<Integer> list = periods.stream()
.flatMap(m -> Stream.of(m.getFrom(), m.getTo()))
.collect(Collectors.toList());
Вывод кода в вашем вопросе: [1, 3, 5, 2, 4, 6]
(вместо [1, 2, 3, 4, 5, 6]
).
Если вам нужен такой вывод, вот способ без использования Stream.flatMap
:
List<Integer> values = Stream.concat(
periods.stream().map(Period::getFrom),
periods.stream().map(Period::getTo))
.collect(Collectors.toList());
Если вы хотите смешать значения from
и to
, то другие ответы должны работать.
Как указано в комментариях, нет необходимости использовать Stream.mapToInt
, за которым следует Stream.boxed
, так как это без необходимости распаковывает и упаковывает целочисленные значения.
.mapToInt(p -> p.getFrom()).boxed()
эквивалентно.map(p -> p.getFrom())
. Вы просто бесполезно распаковываете и переупаковываете все