【问题标题】:Use Java streams to collect objects generated in a `for` loop使用 Java 流收集在 `for` 循环中生成的对象
【发布时间】:2017-02-16 22:09:45
【问题描述】:

我们如何使用 Java Streams 方法来收集在for 循环中生成的对象?

例如,这里我们通过重复调用YearMonth::atDayYearMonth 表示的一个月中的每一天生成一个LocalDate 对象。

YearMonth ym = YearMonth.of( 2017 , Month.AUGUST ) ;
List<LocalDate> dates = new ArrayList<>( ym.lengthOfMonth() );
for ( int i = 1 ; i <= ym.lengthOfMonth () ; i ++ ) {
    LocalDate localDate = ym.atDay ( i );
    dates.add( localDate );
}

这可以用流重写吗?

【问题讨论】:

    标签: java for-loop collections java-stream


    【解决方案1】:

    可以从 IntStream 开始重写:

    YearMonth ym = YearMonth.of(2017, Month.AUGUST);
    List<LocalDate> dates =
            IntStream.rangeClosed(1, ym.lengthOfMonth())
            .mapToObj(ym::atDay)
            .collect(Collectors.toList());
    

    IntStream 中的每个整数值都映射到所需的日期,然后将日期收集在一个列表中。

    【讨论】:

    • 什么控制List 的实例化? List 背后的具体对象是什么?在Answer by Górkiewicz 中,我看到我们明确定义了ArrayList。这里的任务是如何完成的?我看到toList 的文档说“不保证返回的列表的类型、可变性、可序列化性或线程安全性”。这是否意味着使用的支持具体类与我无关/不关心?这是可以理解和接受的;我只是好奇。
    • 你想要List&lt;LocalDate&gt;,你就明白了。如果你想明确定义应该使用哪个 List 实现,你也可以这样做:Collectors.toCollection(ArrayList::new)
    • Collectors.toCollection(ArrayList::new) 很好,但增加了冗长。
    • 我现在明白了。 [A] 如果我关心List 的具体实现,那么我必须提供一个Supplier,并在对Collectors.toCollection 的调用中传递。在这种情况下,Supplier 采用方法引用ArrayList::new 的形式。 [B] 如果我关心实现List 接口的具体类,请使用您的答案中看到的更短更简单的代码。
    【解决方案2】:

    IntStream 替换你的 for 循环:

    YearMonth ym = YearMonth.of(2017, Month.AUGUST);
    List<LocalDate> dates = new ArrayList<>(ym.lengthOfMonth());
    IntStream.rangeClosed(1, ym.lengthOfMonth())
             .forEach(i -> dates.add(ym.atDay(i)));
    

    【讨论】:

    • 投反对票?这怎么不是对这个问题的成功回答?请解释。这个答案赢得了我的赞成票。
    • 谢谢,巴兹尔。我不够快:p
    • 这里和那里一分钟不值得投反对票。也赢得了我的加一(虽然我不是反对者)
    • 谢谢,@i_am_zero。
    【解决方案3】:

    在 Java 9 中,datesUntil 添加了一个特殊方法 LocalDate,它可以生成日期流:

    LocalDate start = LocalDate.of(2017, Month.AUGUST, 1);
    List<LocalDate> dates = start.datesUntil(start.plusMonths(1))
            .collect(Collectors.toList());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-11
      • 2020-02-03
      相关资源
      最近更新 更多