我试图创建两个列表的地图。 First List用于键,第二列用于隔离和赋值,其中没有匹配bin的值的情况将是空List。应该将值分配给键值5 <50,60),因此具有
sampleBins = Arrays.asList(0,10,20,30,40,50,60);
samples = Arrays.asList(5,6,55,52);
我希望地图有关键:0,1,2,3,4,5,6。 键1,2,3,4,6的空列表。 列表中的5个,6个分配给键0和55,52分配给5。
现在我有这样的,它正在工作,但我正在寻找更好的东西,例如,解决方案不需要sampleBins并且适合一个管道
private Map<Integer, List<Integer>> segregateSamples(List<Double> sampleBins, List<Double> samples) {
Map<Integer, List<Integer>> segregatedSamples = sampleBins.stream()
.collect(Collectors.toMap(bin -> bin.intValue() / 10, bin -> new ArrayList<>()));
samples.stream()
.map(Double::intValue)
.collect(Collectors.groupingBy(this::binNumber))
.forEach(segregatedSamples::put);
return segregatedSamples;
}
private Integer binNumber(int value) {
return Math.floorDiv(value, 10);
}
答案 0 :(得分:1)
这是我的第一个解决方案,它基本上将您的解决方案整合到一个声明中。请注意,使用大型列表执行此操作非常昂贵,因此我会在此期间寻找更高效的内容:
sampleBins.stream()
.collect(Collectors.toMap(bin -> bin / 10, bin ->
samples.stream()
.filter(i -> i - i % 10 == bin)
.collect(Collectors.toList())
));
这输出以下内容:
{0 = [5,6],1 = [],2 = [],3 = [],4 = [],5 = [55,52],6 = []}
这是另一个非常简单的解决方案:
samples.stream().collect(Collectors.groupingBy(i -> i - i % 10));
但是,它会输出以下内容,而不是将其他分档设置为空List
s,这可能是您的案例中可能有问题,也可能不是,因为您可以简单地检查bin是否作为密钥存在于Map
:
{0 = [5,6],50 = [55,52]}
如果我发现其他任何有趣内容,我会编辑我的帖子,所以请留意!
答案 1 :(得分:1)
如何使用concat列表然后创建单个并行流?
private Map<Integer, Collection<Integer>> segregateSamples(List<Double> sampleBins, List<Double> samples) {
Stream<Double> d = Stream.concat(sampleBins.stream(), samples.stream()).parallel();
return d.collect(Collectors.groupingByConcurrent(p -> (p.intValue() / 10),
Collectors.mapping(Double::intValue, Collectors.toCollection(ArrayDeque::new))));
}
唯一的缺点是每个集合都包含其密钥。