【问题标题】:Java 8 - Initialising List (List)Java 8 - 初始化列表(List)
【发布时间】:2015-10-02 11:55:38
【问题描述】:

我有一个关于 Java 8 和列表的问题。是否可以比我下面的代码更容易地初始化列表?

final List<List<ScheduleIntervalContainer>> weekScheduler = new ArrayList<>();

weekScheduler.add(0, new ArrayList<ScheduleIntervalContainer>());
weekScheduler.add(1, new ArrayList<ScheduleIntervalContainer>());
weekScheduler.add(2, new ArrayList<ScheduleIntervalContainer>());
weekScheduler.add(3, new ArrayList<ScheduleIntervalContainer>());
weekScheduler.add(4, new ArrayList<ScheduleIntervalContainer>());
weekScheduler.add(5, new ArrayList<ScheduleIntervalContainer>());
weekScheduler.add(6, new ArrayList<ScheduleIntervalContainer>());

【问题讨论】:

  • 你可以在 for 循环中完成。
  • 我会使用一个循环并将其隐藏在扩展 ArrayList 的“WeekScheduler”类中,然后我就不必再次查看代码......永远。

标签: java java-8 java-stream


【解决方案1】:

我个人只会使用for 循环:

List<List<ScheduleIntervalContainer>> weekScheduler = new ArrayList<>();
for (int i = 0; i < 7; i++)
    weekScheduler.add(new ArrayList<>());

但是,如果您想要 Java 8 解决方案:

List<List<ScheduleIntervalContainer>> weekScheduler 
        = Stream.generate(ArrayList<ScheduleIntervalContainer>::new)
                .limit(7)
                .collect(Collectors.toList());

【讨论】:

    【解决方案2】:

    你可以使用:

    List<List<ScheduleIntervalContainer>> weekScheduler = 
         IntStream.rangeClosed(0, 6).mapToObj(i -> new ArrayList<ScheduleIntervalContainer>())
                                    .collect(Collectors.toList());
    

    这将创建一个 int 值从 0 到 6(包括在内)的 Stream,将每个 int 映射到您班级的新 ArrayList 并将结果收集到 List

    【讨论】:

    • 您的代码对我不起作用。它抱怨试图将ArrayList&lt;ScheduleIntervalContainer&gt; 转换为ArrayList&lt;Object&gt;
    • @Tom 你确定你正确复制了吗?并正确导入了 java.util.List?这段代码对我来说编译得很好(JDK 1.8.0_51)
    • @Holger 这就是我的答案!
    • @Paul Boddington:不幸的是,这是设计上的限制,正如here 解释的那样,推理不会传播到方法调用的 receiver,因此不会使用链式调用。目前尚不清楚是否以及何时取消此限制。
    • 您应该注意,这段代码有一个有意的(尽管无害的)副作用。 mapToObj 需要一个使用 int 的函数。因此,方法引用ArrayList::new 将在此处解析为ArrayList&lt;&gt;(int) 构造函数。换句话说,数字06 被误解为创建列表的初始容量。在这里使用i-&gt;new ArrayList&lt;ScheduleIntervalContainer&gt;() 会更干净……
    【解决方案3】:

    您可以使用循环或 IntStream。

    final List<List<ScheduleIntervalContainer>> weekScheduler = new ArrayList<>();
    IntStream.range(0, 7).forEach(day -> weekScheduler.add(new ArrayList<>()));
    

    【讨论】:

    • You shouldn't use stream API's forEach to change state。这是函数式 API 上的命令式编程。您应该改用mapcollect 的组合。
    • @Peter Lawrey:这并不简单,因为您在示例中省略了 weekScheduler 列表的创建。让流创建列表不会使代码更复杂。
    • @PeterLawrey 我不是那个说它的人,您需要与 Oracle 合作。如果你那么喜欢命令式编程,为什么要首先使用流 API?还是我们都应该开始在我们的答案中发布不好的做法,只是因为我们觉得它更好?
    • @Peter Lawrey:但这不是函数式编程风格或流 API 的产物,而是有限的类型推断。没有限制,您可以使用…-&gt;new ArrayList&lt;&gt;()ArrayList::new
    • @PeterLawrey 实际上你的回答仍然被认为是不好的做法,很容易纠正。同样,我们是否都应该开始在我们的答案中发布不良做法,因为我们认为这是正确的?
    【解决方案4】:

    每当我使用列表进行编码时,我都会使用 for 循环来加快声明速度。在您的情况下,我强烈建议使用任何类型的循环,但 for 循环可能是最简单的。

    【讨论】:

      猜你喜欢
      • 2015-08-04
      • 1970-01-01
      • 1970-01-01
      • 2019-04-16
      • 2016-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-13
      相关资源
      最近更新 更多