【问题标题】:How do I merge Objects in a ArrayList?如何合并 ArrayList 中的对象?
【发布时间】:2021-06-11 15:47:51
【问题描述】:

我有一个名为变量 (ArrayList-Variable-) 的对象数组列表(- 代替了

例如:

ArrayList : [VarA: 1, VarA: 6, VarB: 9, VarB: 3, VarA: 4, VarC: 2, VarC: 1]

我想要的是:[VarA: {1,6,4}, VarB: {9,3}, VarC: {2,1}]

我怎样才能做到这一点?

【问题讨论】:

  • 您说每个对象都有一个整数数组,但在您的示例中每个 Var 只显示一个值。这会影响我们可能提供的任何帮助。请澄清。

标签: java arrays arraylist


【解决方案1】:

您可以简单地使用 HashMap 来存储此类数据 假设您的 ArrayList 的变量是 arr 然后:-

HashMap<String, Set<Integer>> map = new HashMap<>();
for(Variable var:arr) {
   Set<Integer> set = map.getOrDefault(var.name, new HashSet<Integer>());
   set.add(var.domain);
   map.put(var.name, set);
}

然后 ma​​p (HashMap) 将包含所需的结果,如果需要,您可以再次将其转换为 ArrayList

【讨论】:

    【解决方案2】:

    我会使用列表的 Hashmap 来实现。

    for (Tuple item: list) {
        if (!map.containsKey(item.key)) {
            map.put(item.key, new LinkedList<String>());
        }
        map.get(item.key).add(item.value);
    }
    

    然后使用 map.values() ,您可以恢复值列表的集合。

    【讨论】:

      【解决方案3】:

      使用 Java 8 Stream,您可以执行以下操作:

      Map<String, Set<Integer>> result = v.stream().collect(
              Collectors.groupingBy(Variable::getDomain, 
                  HashMap::new, Collectors.mapping(Variable::getVal, Collectors.toSet()))
            );
      

      测试代码:

      List<Variable> v = new ArrayList<Variable>();
      v.add(new Variable("A", 1));
      v.add(new Variable("A", 2));
      v.add(new Variable("B", 4));
      v.add(new Variable("C", 7));
      v.add(new Variable("C", 7));
      
       Map<String, Set<Object>> result = v.stream().collect(
          Collectors.groupingBy(Variable::getDomain, 
              HashMap::new, Collectors.mapping(Variable::getVal, Collectors.toSet()))
        );
      System.out.println(result);
      

      输出: {A=[1, 2], B=[4], C=[7]}

      变量类:

      class Variable {
      
        private String domain;
      
        private int val;
      
        public Variable(String domain, int val) {
          this.domain = domain;
          this.val = val;
        }
      
        /**
         * @return the domain
         */
        public String getDomain() {
          return domain;
        }
      
        /**
         * @param domain
         *          the domain to set
         */
        public void setDomain(String domain) {
          this.domain = domain;
        }
      
        /**
         * @return the val
         */
        public int getVal() {
          return val;
        }
      
        /**
         * @param val
         *          the val to set
         */
        public void setVal(int val) {
          this.val = val;
        }
      
      }
      

      【讨论】:

      • 他们问题中的 OP 状态。 域是一个 int 数组。
      • @WJS 例如它提到了 ArrayList。这是示例代码,因为从数组/列表转换非常简单。
      【解决方案4】:

      你已经有一个清单了吗?您可以使用 groupingBy。

      Map<String, List<Integer>> grouped = list.stream().collect( Collectors.groupingBy( Variable::getGroup ) );
      

      【讨论】:

        【解决方案5】:
        • 这会创建一些实例(记录)的List,这些实例(记录)在数组中具有相似名称的重复值。
        • 它使用 hashMap 来存储名称和域,利用 computeIfAbsent 如果它不存在则首先创建集合,否则,将数组添加到其中。该集合的目的是消除重复。
        // your list of objects each with a name and Integer[] domain   
        List<Variable> vars = List.of(new Variable("var1", 1, 2, 3),
                new Variable("var2", 4, 5, 6), new Variable("var1", 1, 9, 10),
                new Variable("var5", 1, 6, 8), new Variable("var2", 4, 8, 9));
            
        Map<String, Set<Integer>> result = new HashMap<>();
        for (Variable v : vars) {
            result.computeIfAbsent(v.name, k -> new HashSet<>())
                    .addAll(Arrays.asList(v.domain));
        }
            
        result.entrySet().forEach(System.out::println);
        
        

        打印

        var5=[1, 6, 8]
        var2=[4, 5, 6, 8, 9]
        var1=[1, 2, 3, 9, 10]
        
        

        根据您的描述的变量类。

        class Variable {
            private String name;
            private Integer[] domain;
            public Variable(String name, Integer... domain) {
                super();
                this.name = name;
                this.domain = domain;
            }
            public String getName() {
                return name;
            }
            public Integer[] getDomain() {
                return domain;
            }   
        }
        

        您也可以使用流来实现。我选择使用flatMapping 收集器将域数组组合成每个名称的集合。

        Map<String,Set<Integer>> result = vars.stream().collect(
                Collectors.groupingBy(v->v.getName(),
                   Collectors.flatMapping(
                           v->Arrays.stream(v.getDomain()),
                                   Collectors.toSet())));
        
        

        这会产生与上面相同的结果。上述两个示例都假设一个整数数组来保存域项。 List&lt;Integer&gt; 会更好。 Arrays.asList 或流操作不容易支持原始数组,但有一些变通方法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-03-16
          • 2023-03-03
          • 2021-11-13
          相关资源
          最近更新 更多