首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GroupingBy a范围日期

GroupingBy a范围日期
EN

Stack Overflow用户
提问于 2021-09-23 08:13:54
回答 1查看 366关注 0票数 3

我遇到了这样的情况:

代码语言:javascript
复制
List<ObjectA> collapsed = list.stream().collect(Collectors.collectingAndThen(
        Collectors.groupingBy(
                ObjectA::getDate,
                Collectors.maxBy(Comparator
                        .comparing(ObjectA::getPriority1)
                        .thenComparing(ObjectA::getPriority2)
                        .thenComparing(ObjectA::getDate)
                        .thenComparing(ObjectA::getId))),
        map -> map.values().stream()
                .filter(Optional::isPresent)
                .map(Optional::get)
                .collect(Collectors.toList())));

而且在相同的日子里也能很好的工作。我只需要对特定日期窗口的项进行分组:

代码语言:javascript
复制
Integer daysWindow = 90;

所以我希望在这个窗口的日期发生一切。这怎么可能?

感谢大家!

EN

回答 1

Stack Overflow用户

发布于 2021-09-23 09:07:25

作为另一种方法,如果您要寻找的是对应值的日期范围映射,则可以通过创建范围数据类型,然后在该类型上生成组,为其提供更多的工作。下面是一个例子:

代码语言:javascript
复制
class DateRange {
    private final LocalDate from;
    private final int length;

    public DateRange(LocalDate from, int length) {
        super();
        this.from = from;
        this.length = length;
    }

    //getters

    @Override
    public int hashCode() {
        return this.from.hashCode(); //TODO
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof DateRange))
            return false;
        
        DateRange r = (DateRange) obj;

        return this.length == r.length && this.from.equals(r.from);
    }

    @Override
    public String toString() {
        return "(" + from + " to " + from.plusDays(length) + ")";
    }
}

然后,您的流可以创建一个映射,就像您当前拥有的映射一样,但是在确定每个元素所属的范围之后,可以在日期范围上进行分组。

代码语言:javascript
复制
int daysWindow = 60;
var start = LocalDate.of(2021, 1, 1);

//example date list
List<LocalDate> dates = List.of(start.plusDays(20), 
        start.plusDays(30), start.plusDays(40), start.plusDays(50),
        start.plusDays(60), start.plusDays(70), start.plusDays(80));

var ranges = dates.stream()
        .collect(Collectors.groupingBy(d -> {
            var diff = ChronoUnit.DAYS.between(start, d);
            return new DateRange(start.plusDays(diff - diff % daysWindow), daysWindow);
        }));

当然,您将使用当前收集器,我只想显示对groupingBy的调用,您仍然可以使用下游收集器调用该调用。

需要确定的一件事是start的值。我假设这可以设置为集合中的min日期,尽管它也可以是用户定义的。

上述代码的输出如下:

代码语言:javascript
复制
{(2021-03-02 to 2021-05-01)=[2021-03-02, 2021-03-12, 2021-03-22], 
 (2021-01-01 to 2021-03-02)=[2021-01-21, 2021-01-31, 2021-02-10, 2021-02-20]}

当使用不同的窗口进行测试时,int daysWindow = 90;

代码语言:javascript
复制
{(2021-01-01 to 2021-04-01)=[2021-01-21, 2021-01-31, 2021-02-10, 
                             2021-02-20, 2021-03-02, 2021-03-12, 2021-03-22]}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69296325

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档