java - 如何在空列表中使用 Java Stream

标签 java java-8 java-stream

我需要在此代码中使用 Java Stream,但我不知道它如何处理空列表。

我试图在 Stream Java 8 中找到类似 while 的内容,但找不到。

public static List<DateBucket> bucketize(ZonedDateTime fromDate, ZonedDateTime toDate, int bucketSize, ChronoUnit bucketSizeUnit) {

    List<DateBucket> buckets = new ArrayList<>();;
    boolean reachedDate = false;

    for (int i = 0; !reachedDate; i++) {
        ZonedDateTime minDate = fromDate.plus(i * bucketSize, bucketSizeUnit);
        ZonedDateTime maxDate = fromDate.plus((i + 1) * bucketSize, bucketSizeUnit);
        reachedDate = toDate.isBefore(maxDate);
        buckets.add(new DateBucket(minDate.toInstant(), maxDate.toInstant()));
    }

    return buckets;
}

我希望在代码的主要部分中避免使用 for 并使用 Stream。

最佳答案

您可以使用 LongStream 启动并使用 mapToObj() 创建您的 DateBucket:

public static List<DateBucket> bucketize(ZonedDateTime fromDate, ZonedDateTime toDate, int bucketSize, ChronoUnit bucketSizeUnit) {
    return LongStream.rangeClosed(0, bucketSizeUnit.between(fromDate, toDate))
            .mapToObj(i -> {
                ZonedDateTime minDate = fromDate.plus(i * bucketSize, bucketSizeUnit);
                ZonedDateTime maxDate = fromDate.plus((i + 1) * bucketSize, bucketSizeUnit);
                return new DateBucket(minDate.toInstant(), maxDate.toInstant());
            })
            .filter(b -> {
                ZonedDateTime maxDate = b.getMaxDate().atZone(toDate.getZone());
                ZonedDateTime limitDate = toDate.plus(bucketSize, bucketSizeUnit);
                return maxDate.isBefore(limitDate) || maxDate.isEqual(limitDate);
            })
            .collect(Collectors.toList());
}

这会创建一个从 0 到给定日期之间的最大可能索引的 IntStream,将每个索引映射到 DateBucket 并过滤所需范围的结果。

如果您可以使用Java 9,我建议使用IntStream.iterate()而不是Intstream.rangeClosed() takeWhile() 而不是 filter():

public static List<DateBucket> bucketize(ZonedDateTime fromDate, ZonedDateTime toDate, int bucketSize, ChronoUnit bucketSizeUnit) {
    return LongStream.iterate(0, i -> i + 1)
            .mapToObj(i -> {
                ZonedDateTime minDate = fromDate.plus(i * bucketSize, bucketSizeUnit);
                ZonedDateTime maxDate = fromDate.plus((i + 1) * bucketSize, bucketSizeUnit);
                return new DateBucket(minDate.toInstant(), maxDate.toInstant());
            })
            .takeWhile(b -> {
                ZonedDateTime maxDate = b.getMaxDate().atZone(toDate.getZone());
                ZonedDateTime limitDate = toDate.plus(bucketSize, bucketSizeUnit);
                return maxDate.isBefore(limitDate) || maxDate.isEqual(limitDate);
            })
            .collect(Collectors.toList());
}

但是这些方法的性能都不会比您已有的解决方案更好。

关于java - 如何在空列表中使用 Java Stream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55536044/

相关文章:

使用 lambda 表达式时 Java 8 泛型 + 异常编译时错误

java同步线程说明

java - 为什么使用 for 循环的倒数总和比流快 400 倍?

java-8 - 使用 Files.lines 修改文件

java - 使用 java8 过滤器比较两个整数列表

java - Hibernate Search、Lucene 或任何其他替代方案?

java - 获取所有 JAR 文件中所有类中带注释 @Test 的所有方法

java - 将字符串转换为日期 - 罗马月

java - 在 Spring MVC 中显式使用 POST 请求值

CMD 上不显示 JAVA 版本