[英]JAVA: How do I merge objects from an arrayList based on a property value?
[英]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
,这些实例(记录)在数组中具有相似名称的重复值。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.