【问题标题】:For loop optimisation with Java8使用 Java8 进行循环优化
【发布时间】:2017-07-14 08:50:39
【问题描述】:

如何做到这一点?

我目前正在尝试这样做

例子:

{{"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());
    });
});

我怎样才能只用 1 行?

【问题讨论】:

  • 通过删除换行符 ... ?
  • 这个问题有点荒谬。首先最重要的是REAL优化(时间+数据),行数只是为了可读性。当我看到某些代码不再更改时,有时我会删除换行符,以便更快地滚动代码。但仅此而已。
  • 我的意思是要避免两个 foreach 循环并用一个 foreach 循环来做。有可能吗?
  • 是的,ID 是唯一的

标签: for-loop foreach java-8


【解决方案1】:

由于 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 转换为结果Map 的条目,并将val 转换为List&lt;Integer&gt; 的元素。

【讨论】:

    【解决方案2】:

    假设您有这样的输入:

    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

    【讨论】:

    • 不要认为这比 OP 中的代码短很多。
    • 我的意思是要避免两个 foreach 循环并用一个 foreach 循环来做。有可能吗?
    猜你喜欢
    • 2020-06-14
    • 1970-01-01
    • 2019-10-15
    • 2021-12-05
    • 2021-05-05
    • 1970-01-01
    • 1970-01-01
    • 2012-11-05
    • 2016-10-24
    相关资源
    最近更新 更多