如何将 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());
}

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

你需要

Stream.iterate来生成一个列表,你需要提供两个参数,第一个是初始参数,第二个是处理上一个参数并返回下一个参数的函数:

        public static List<DateBucket> bucketize(ZonedDateTime fromDate, ZonedDateTime toDate, int bucketSize, ChronoUnit bucketSizeUnit) {
                List buckets = Stream.iterate(
                                new DateBucket(
                                        fromDate.toInstant(),
                                        fromDate.plus(bucketSize, bucketSizeUnit).toInstant()
                                ),
                                (DateBucket db) -> new DateBucket(db.to, db.to.plus( bucketSize, bucketSizeUnit))
                        )
                        .limit(bucketSizeUnit.between(fromDate, toDate) / bucketSize)
                        .collect(Collectors.toList());
                return buckets;
        }

相关内容

最新更新