假设我有一个班级
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
解决了这个问题(这不是必需的),我想知道是否可以使用列表操作合并列表,并在对象的字段上完成添加并显示输出ArrayList
本身?
答案 0 :(得分:1)
扩展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}]
答案 1 :(得分:0)
您可以使用JDK 8+之后提供的 stream
API。
作为以下给定解决方案的一部分,首先我将所有子列表合并为main
为List
的{{1}},其中包含List
列表
main.stream()
.flatMap(List::stream)
.collect(Collectors.toList())
现在,Name
可以轻松 groupingby
并计算其值,这将返回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())));
因为,您的最终输出为List
。因此,我们遍历地图并将其添加到List
。
//add into dummy List
map.entrySet().stream().forEach((e) -> {
last.add(new xyz(e.getKey(), e.getValue()));
});
我将不胜感激任何建议和/或改进。