繁体   English   中英

如何合并 ArrayList 中的对象?

[英]How do I merge Objects in a ArrayList?

我有一个名为变量(ArrayList-Variable-)的对象的 arraylist ( - 代替了 <,否则会触发引用)。 这个变量 object 有两个字段:name 和 domain,其中 name 是 String,domain 是 int 数组。 我想合并具有相同名称的变量,特别是我希望有一个具有该名称的变量,并且域等于具有相同名称的变量的所有域的联合(不重复)。

例如:

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}]

我怎样才能做到这一点?

您可以简单地使用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);
}

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

我会使用列表的 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(),您可以恢复值列表的集合。

使用 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);

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

变量 Class:

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;
  }

}

你已经有清单了吗? 您可以使用分组依据。

Map<String, List<Integer>> grouped = list.stream().collect( Collectors.groupingBy( Variable::getGroup ) );
  • 这将创建一些实例(记录)的List ,这些实例(记录)在数组中具有相似名称的重复值。
  • 它使用 hashMap 来存储名称和域,如果它不存在,则利用computeIfAbsent首先创建集合,否则,将 arrays 添加到其中。 该集合的目的是消除重复。
// 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。

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收集器将域 arrays 组合成每个名称的集合。

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

这产生与上面相同的结果。 上述两个示例都假设使用 Integer 数组来保存域项。 List<Integer>会更好。 Arrays.asList或 stream 操作不容易支持原始 arrays,但有一些解决方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM