Java 8 Streams - собрать несколько полей Integer из списка объектов

Например, у меня есть класс:

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]

Есть ли какой-либо другой вариант управления потоком для достижения того же результата?

.mapToInt(p -> p.getFrom()).boxed() эквивалентно .map(p -> p.getFrom()). Вы просто бесполезно распаковываете и переупаковываете все
Michael 11.12.2020 15:33
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
1
924
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Поток по периодам, для каждого элемента создайте новый поток обоих атрибутов и сгладьте их.

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, так как это без необходимости распаковывает и упаковывает целочисленные значения.

Другие вопросы по теме