在流中查找的值少于几倍,然后是最大值

问题描述 投票:0回答:2

我想找到比实际最长日期长一年的第一个日期。我尝试用溪流做但我被卡住了。

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();

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

java java-8 java-stream
2个回答
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();
}

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,无需任何修改。

© www.soinside.com 2019 - 2024. All rights reserved.