使用java 8按任意间隔对Map进行分组

Eko*_*ilo 4 java functional-programming java-8

我有数据表示为正双数列表,以及包含将用于分组数据的间隔的列表.间隔始终排序.
我尝试使用以下实现对数据进行分组

    List<Double> data = DoubleStream.generate(new Random()::nextDouble).limit(10).map(d -> new Random().nextInt(30) * d).boxed().collect(Collectors.toList());
    HashMap<Integer, List<Double>> groupped = new HashMap<Integer, List<Double>>();
    data.stream().forEach(d -> {
        groupped.merge(getGroup(d, group), new ArrayList<Double>(Arrays.asList(d)), (l1, l2) -> {
            l1.addAll(l2);
            return l1;
        });
    });
    public static Integer getGroup(double data, List<Integer> group) {

    for (int i = 1; i < group.size(); i++) {
        if (group.get(i) > data) {
            return group.get(i - 1);
        }
    }
    return group.get(group.size() - 1);
}
    public static List<Integer> group() {
       List<Integer> groups = new LinkedList<Integer>();
       //can be arbitrary groupping
       groups.add(0);
       groups.add(6);
       groups.add(11);
       groups.add(16);
       groups.add(21);
       groups.add(26);
       return groups;
   }
Run Code Online (Sandbox Code Playgroud)

是否可以通过收集器直接执行数据逻辑来执行这种灌浆/减少?

另外,考虑到过程的复杂性,这应该花费n ^ 2,因为我们迭代两个列表(或流).现在它不是并行的,但我认为可以在paralel中执行getGroup().应该使用任何Insight应该使用TreeSet还是List来获得更好的性能?

Flo*_*own 5

您可以对代码进行大量改进.Random支持StreamAPI.所以不需要生成自己的DoubleStream.
接下来,您应该只生成一次边界集.
最后一件事就是Collector::groupingBy为你做的工作.


import java.util.List;
import java.util.Map;
import java.util.NavigableSet;
import java.util.Random;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.stream.Collectors;

public class Test {

  public static void main(String... args) {
    Random r = new Random();
    List<Double> data = r.doubles(10).map(d -> r.nextInt(30) * d).peek(System.out::println).boxed()
        .collect(Collectors.toList());
    NavigableSet<Integer> groups = group();
    Map<Integer, List<Double>> groupped = data.stream()
        .collect(Collectors.groupingBy(d -> groups.floor(d.intValue()), TreeMap::new, Collectors.toList()));
    System.out.println(groupped);
  }

  public static NavigableSet<Integer> group() {
    NavigableSet<Integer> groups = new TreeSet<>();
    groups.add(0);
    groups.add(6);
    groups.add(11);
    groups.add(16);
    groups.add(21);
    groups.add(26);
    return groups;
  }
}
Run Code Online (Sandbox Code Playgroud)