【问题标题】:Using group by in java 8在 java 8 中使用 group by
【发布时间】:2017-01-18 01:20:23
【问题描述】:

我有一个Set<CarRange> 和一个List<Car> 作为方法的输入。我需要对类似的汽车进行分组并返回类似Map<CarRange, List<Car>> 的内容。如何使用 java 8 流实现这一点?

class CarRange {
int startId;
int endId;
}

class Car {
int carId;   
}

因此,如果 carId 位于 startId 和 endId 之间,则它属于该 CarRange 对象。对于Set<CarRange> 中的每个元素,startId 和 endId 将是唯一的。希望它更清楚一点。

【问题讨论】:

标签: java java-8 java-stream


【解决方案1】:

坦率地说,我不会对流执行此操作,这实际上不是流 API 意义上的“分组依据”操作,因此“分组依据”收集器不会执行您明显想要的操作。以下或多或少可以满足您的需求,但它是令人反感的代码:

    Map<CarRange,List<Car>> map = 
            ranges.stream()
                .collect(
                    Collectors.toMap(
                        range -> range, 
                        range -> cars.stream()
                            .filter(car -> range.carInRange(car))
                            .collect(Collectors.toList())
                    )
                );

显然,我在 CarRange 类中添加了“carInRange”方法,以避免使示例变得比现在更混乱。

【讨论】:

  • 如果您有一种方法可以从汽车中找到范围,则可以将其设为“分组依据”。
【解决方案2】:

我知道您对 Jonathan Essex 的回答很满意,我并不想说服您接受其他任何事情。我只是被“这实际上不是流 API 意义上的‘分组’操作”这句话激怒了,并想证明如果你愿意,你可以这样看待它:

    CarRange misc = new CarRange(); // for any cars that don’t belong in any other range
    Map<CarRange, List<Car>> map = cars.stream()
            .collect(Collectors.groupingBy(c -> 
                ranges.stream()
                    .filter(r -> r.carInRange(c))
                    .reduce((r1, r2) -> { throw new IllegalArgumentException("Overlapping ranges " + r1 + " and " + r2); })
                    .orElse(misc)
    ));
    System.out.println("Cars without range? " + map.get(misc));

像乔纳森一样,我假设CarRange 有一个carInRange 方法。我的代码大小差不多。一个可能的优势是它会捕捉到汽车是否属于两个范围,并且很容易检查汽车是否根本不属于任何范围;我在最后一行做后者。两个 sn-ps 可能同样低效,我的可能是最低效的;如果有更快的方法来找到给定汽车的范围,则可以优化按方法分组。如果需要,我们可以发明。

【讨论】:

  • 不确定这是否有本质上的不同,因为它仍然是一个嵌套迭代(我们在汽车集合和范围集合上都调用了“stream()”)。我关于“​​groupBy”流 API 的意图的陈述是基于“groupBy”实际上旨在处理正在流式传输的对象固有的某些属性的想法,因此可以在没有双重迭代的情况下执行分组操作。我同意,毫无保留,该声明具有挑衅性。很好地使用“减少”来标记重叠范围,这太酷了。但我认为我的更容易理解。
猜你喜欢
  • 1970-01-01
  • 2018-01-10
  • 2022-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-18
  • 1970-01-01
相关资源
最近更新 更多