代码之家  ›  专栏  ›  技术社区  ›  Hari_pb

如何在Java中按列表的名称对列表进行分组

  •  1
  • Hari_pb  · 技术社区  · 7 年前

    假设我有课

    class X {
        String name;
        int value; 
    }
    

    ArrayList

    [{A,2}, {B,1}, {C,3}]
    [{C,5}, {D,1}]
    [{A,3}, {D,1}]
    

    现在,我想将列表与具有相同名称的对象合并,并求和这些值,以便最终输出如下所示

    [{A,5}, {B,1}, {C,8}, {D,2}]
    

    这个问题我用 HashMap 阵列列表 它本身

    2 回复  |  直到 7 年前
        1
  •  1
  •   Robin Alex Panicker    7 年前

    扩展ArrayList以构建合并功能。

    package com.test;
    import java.util.ArrayList;
    
    public class MyArrayList<P> extends ArrayList<Pair> {
        public static void main(String[] args) {
           Pair p1 = new Pair ("A", 2);
           Pair p2 = new Pair ("B", 4);
           Pair p3 = new Pair ("C", 1);
    
           MyArrayList<Pair> l1 = new MyArrayList<Pair>();
           l1.add(p1);
           l1.add(p2);
           l1.add(p3);
    
           Pair p4 = new Pair ("A", 5);
           Pair p5 = new Pair ("C", 10);
           Pair p6 = new Pair ("D", 12);
    
           ArrayList<Pair> l2 = new ArrayList<Pair>();
           l2.add(p4);
           l2.add(p5);
           l2.add(p6);
    
           l1.merge(l2);
           System.out.println(l1.toJson());
    
        }
    
       @Override
       public boolean add(Pair e) {
           Pair p = this.getPair(e);
           if (p == null) return super.add(e);
           p.value += e.value;
           return true;
       }
    
       public void merge (ArrayList<Pair> list) {
           for(Pair p : list) this.add(p);
       }
    
       public String toJson() {
           StringBuffer s = new StringBuffer("[");
           for(Pair p : this) s.append("{\"name\":").append("\"").append(p.name).append("\",").append("\"value\":").append(p.value).append("},");
           return s.append("]").deleteCharAt(s.length()-2).toString();
       }
    
       private Pair getPair (Pair e) {
           for(Pair p : this) if (p.name.equals(e.name)) return p;
           return null;
       }
    }
    

    配对类

    package com.test;
    public class Pair {
       String name;
       int value;
       public Pair(String name, int value) {
          super();
          this.name = name;
          this.value = value;
       }
    }
    

    [{"name":"A","value":7},{"name":"B","value":4},{"name":"C","value":11},{"name":"D","value":12}]
    
        2
  •  0
  •   Ravi    7 年前

    你可以用 stream API,可在JDK 8+之后使用。

    作为下面给出的解决方案的一部分,首先我将所有子列表合并到一个 main List ,其中包含 列表的数量

      main.stream()
          .flatMap(List::stream)
          .collect(Collectors.toList())
    

    groupingby 他们 Name 并计算其值,这将返回一个 Map

    .stream()
    .collect(Collectors.groupingBy(w -> w.getName(), Collectors.summingInt(w -> w.getValue())))
    

        //create dummy List
        List<xyz> last = new ArrayList<>();
    
        //merge all list into one and they apply group by to sum
        Map<String, Integer> map = main.stream()
                                       .flatMap(List::stream)
                                       .collect(Collectors.toList())
                                       .stream()
                                       .collect(Collectors.groupingBy(w -> w.getName(), Collectors.summingInt(w -> w.getValue())));
    

    因为,您的最终输出为 列表 . 因此,我们遍历地图并将其添加到 .

        //add into dummy List
        map.entrySet().stream().forEach((e) -> {
            last.add(new xyz(e.getKey(), e.getValue()));
        });
    

    如有任何建议和/或改进,我将不胜感激。