用Java8进行循环优化

时间:2017-07-14 08:50:40

标签: for-loop foreach java-8

如何用一条线实现这一目标?

我目前正在尝试这样做

示例:

{{"id" :"2", values: ["10","11", "12"]} , {"id" : "3", values : ["23"]}}

{{"id" :"2","value": "10"},{"id": "2","value":"11"},
 {"id" :"3","value":"23"} , {"id" : "2", "value":"12"}}

我的java代码是

Map<Integer, List<Integer>> attrMap = new HashMap<>();
//getAllData() & item.getValues() both returns List

getAllData().forEach(item - > {
    item.getValues().forEach(val - > {
        attrMap.computeIfAbsent(item.getId(), (k) - > 
        new ArrayList < > ()).add(val.getValue());
    });
});

我怎么能只做一行?

2 个答案:

答案 0 :(得分:5)

由于ID是唯一的,您可以像

那样进行
Map<Integer, List<Integer>> attrMap = getAllData().stream()
  .collect(Collectors.toMap(
    item -> item.getId(),
    item -> item.getValues().stream().map(i->i.getValue()).collect(Collectors.toList())));

但是,当然,这仍然具有两个嵌套循环的性能特征。但它会支持并行处理,但我怀疑你的数据是否足以从并行处理中获益。

此外,请注意,生成的地图仍然在结构上与您的第一个模式匹配,

{{"id" :"2", values: ["10","11", "12"]} , {"id" : "3", values : ["23"]}}

您刚刚将item转换为结果Mapval的条目List<Integer>的元素。

答案 1 :(得分:1)

假设你有这样的输入:

static class Data {
    private final int id;

    private final List<Integer> values;

    public int getId() {
        return id;
    }

    public List<Integer> getValues() {
        return values;
    }

    public Data(int id, List<Integer> values) {
        super();
        this.id = id;
        this.values = values;
    }
}

可以通过以下方式完成:

 List<SimpleEntry<Integer, Integer>> result = Arrays.asList(
           new Data(2, Arrays.asList(10, 11, 12)), 
           new Data(3, Arrays.asList(23)))
              .stream()
              .flatMap(d -> d.getValues().stream().map(x -> new AbstractMap.SimpleEntry<>(d.getId(), x)))
            .collect(Collectors.toList());

    System.out.println(result); // [2=10, 2=11, 2=12, 3=23]

我正在收集PairAbstractMap.SimpleEntry的内容。