在流中查找比最大值少几倍的值

时间:2018-06-20 09:07:57

标签: java java-8 java-stream

我想查找第一个日期早于实际最大日期的一年。我尝试对流进行处理,但是卡住了。

List<String> intervalIdList = new HashSet();

intervalIdList.add("2018-01");
intervalIdList.add("2017-12");
intervalIdList.add("2017-11");
intervalIdList.add("2017-10");
...
intervalIdList.add("2016-12"); // this is the value I want to find

LocalDate localDateSet =
                    intervalIdSet.stream()
                            .map(s-> LocalDate.parse(s))
                            .sorted()
                            .filter(localDate -> localDate < max(localDate)) // something like max(localDate)
                            .findFirst();

我必须将最大过滤值写入流外部的变量吗?

2 个答案:

答案 0 :(得分:2)

您正在寻找的是今天前一年的最大日期:

List<String> intervalIdList = new ArrayList<>();

intervalIdList.add("2018-01-01");
intervalIdList.add("2017-12-01");
intervalIdList.add("2017-11-01");
intervalIdList.add("2017-10-01");
intervalIdList.add("2016-12-01"); // this is the value I want to find

LocalDate localDateSet = intervalIdList.stream()
        .map(LocalDate::parse)
        .filter(ld -> ld.isBefore(LocalDate.now().minus(Period.of(1, 0, 0))))
        .max(Comparator.comparingLong(LocalDate::toEpochDay))
        .get();

System.out.println(localDateSet);

显示2016-12-01

请注意,我必须在日期字符串中添加天数,以匹配LocalDate.parse期望的默认格式。

由于使用了过滤器,为了处理没有值与谓词匹配的情况,显式检查可选选项可能更安全:

Optional<LocalDate> max = intervalIdList.stream()
        .map(LocalDate::parse)
        .filter(ld -> ld.isBefore(LocalDate.now().minus(Period.of(1, 0, 0))))
        .max(Comparator.comparingLong(LocalDate::toEpochDay));

在读取最大值之前进行检查:

if(max.isPresent()) {
    LocalDate ld = max.get();
}

答案 1 :(得分:0)

首先,您必须像这样找到实际的最新日期,

LocalDate latestDate = intervalIdList.stream().map(s -> s.split("-"))
        .map(sp -> LocalDate.of(Integer.parseInt(sp[0]), Integer.parseInt(sp[1]), 1))
        .max(Comparator.comparingLong(LocalDate::toEpochDay)).orElse(null);

然后,我们需要找到所有比最新日期早一年的日期,然后获取它们的最新日期。因此,这段代码可以做到这一点。

LocalDate firstDateOneYearOlder = intervalIdList.stream().map(s -> s.split("-"))
        .map(sp -> LocalDate.of(Integer.parseInt(sp[0]), Integer.parseInt(sp[1]), 1))
        .filter(d -> ChronoUnit.DAYS.between(d, latestDate) > 365)
        .max(Comparator.comparingLong(LocalDate::toEpochDay)).orElse(null);

还请注意,此解决方案使用原始格式为List的原始输入数据,未经任何修改。