【问题标题】:Java 8 Streams - collect multiple Integer fields from list of objects [duplicate]Java 8 Streams - 从对象列表中收集多个整数字段[重复]
【发布时间】:2023-03-27 19:14:01
【问题描述】:

例如我有一个班级:

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。是否有可能在periods 列表中使用stream?我试图做这样的事情:

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())。您只是不必要地拆箱和重新装箱

标签: java collections java-stream


【解决方案1】:

你可以这样做:

List<Integer> list = periods.stream()
        .flatMap(m -> Stream.of(m.getFrom(), m.getTo()))
        .collect(Collectors.toList());

【讨论】:

    【解决方案2】:

    在时间段内流式传输,为每个项目创建两个属性的新流,并将它们展平。

    periods.stream()
        .flatMap(p -> Stream.of(p.getTo(), p.getFrom()))
        .collect(Collectors.toList());
    

    【讨论】:

      【解决方案3】:

      您问题中代码的输出是[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());
      

      如果您想混合使用 fromto 值,那么其他答案应该可以工作。

      正如 cmets 中所指出的,没有必要使用 Stream.mapToInt 后跟 Stream.boxed,因为这会不必要地取消装箱和装箱整数值。

      【讨论】:

        猜你喜欢
        • 2021-04-25
        • 2017-09-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-29
        • 2014-04-29
        相关资源
        最近更新 更多