[英]Add or Update elements of an ArrayList based on another ArrayList
I have two ArrayLists of ClassRoom
object and below shows the ClassRoom
class:我有两个ClassRoom
object 的 ArrayLists,下面显示了ClassRoom
class:
public class ClassRoom {
private String className; // className is unique here
private List<Student> students = new ArrayList<>();
public ClassRoom(String className, List<Student> students) {
this.className = className;
this.students = students;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
@Override
public String toString() {
String ss = "[";
for (int i = 0; i < students.size(); i++) {
ss += "{name:'" + students.get(i).getName() + "',age:" + students.get(i).getAge() + "}";
ss += (i == (students.size() - 1)) ? "" : ",";
}
ss += "]";
return "{'" + className + "':" + ss + "}";
}
}
ClassRoom
class contains className String property and List of Student
object which describes below: ClassRoom
class 包含className String 属性和Student
object 列表,描述如下:
public class Student {
private String name; // name is unique here
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
I have created my two lists of ClassRoom
object like below:我已经创建了两个ClassRoom
object 列表,如下所示:
List<ClassRoom> list1 = new ArrayList<>();
list1.add(new ClassRoom("A", Arrays.asList(new Student("Sam", 20), new Student("Peter", 40), new Student("Aaron", 15))));
list1.add(new ClassRoom("B", Arrays.asList(new Student("Ronnie", 33), new Student("Daniel", 41), new Student("Gabe", 35))));
list1.add(new ClassRoom("C", Arrays.asList(new Student("Fabian", 42), new Student("Edgar", 33))));
list1.add(new ClassRoom("D", Arrays.asList(new Student("Peter", 39), new Student("Calvin", 45))));
List<ClassRoom> list2 = new ArrayList<>();
list2.add(new ClassRoom("A", Arrays.asList(new Student("Sam", 26), new Student("Aaron", 18))));
list2.add(new ClassRoom("B", Arrays.asList(new Student("Daniel", 38), new Student("Eddy", 29))));
list2.add(new ClassRoom("C", Arrays.asList(new Student("Fabian", 42), new Student("Edgar", 33))));
So my final task is to create a new List of ClassRoom
object like below:所以我的最后一项任务是创建一个新的ClassRoom
列表,如下所示:
List<ClassRoom> mergedList = merge(list1, list2);
for (ClassRoom classRoom : mergedList) {
System.out.println(classRoom.toString());
/* Expected output here
{'A':[{name:'Sam',age:26},{name:'Peter',age:40},{name:'Aaron',age:18}]}
{'B':[{name:'Ronnie',age:33},{name:'Daniel',age:38},{name:'Gabe',age:35},{name:'Eddy',age:29}]}
{'C':[{name:'Fabian',age:42},{name:'Edgar',age:33}]}
{'D':[{name:'Peter',age:39},{name:'Calvin',age:45}]}
*/
}
And below explains my merge
method:下面解释了我的merge
方法:
public static List<ClassRoom> merge(List<ClassRoom> listA, List<ClassRoom> listB) {
ArrayList<ClassRoom> collect = Stream.of(listA, listB).collect(ArrayList<ClassRoom>::new, (item1, item2) -> {
item2.forEach((c2) -> {
item1.forEach((c1) -> {
if (c2.getClassName().equalsIgnoreCase(c1.getClassName())) {
// Student list update goes here
} else {
item1.add(c2);
}
});
});
}, (item1, item2) -> {
});
return collect;
}
Problem I am having so far is resulting an empty list after the merge method call.到目前为止我遇到的问题是在合并方法调用后产生一个空列表。 Any suggestions would be appreciated.任何建议,将不胜感激。
equals
and hashCode
methods in Student
on name
.在name
上覆盖Student
中的equals
和hashCode
方法。@Override
public boolean equals(Object obj) {
return Objects.equals(name, ((Student) obj).getName());
}
@Override
public String toString() {
return "name: " + name + ", age: " + age;
}
equals
and hashCode
methods in ClassRoom
using the default implementation suggested by your IDE.使用 IDE 建议的默认实现覆盖ClassRoom
中的equals
和hashCode
方法。list2
into a Map<String, List<Student>> map
and process each element of list1
as shown below:将list2
收集成一个Map<String, List<Student>> map
,对list1
的每个元素进行如下处理:
Map<String, List<Student>> map = list2.stream()
.collect(Collectors.toMap(ClassRoom::getClassName, ClassRoom::getStudents));
list1.forEach(e -> map.merge(e.getClassName(),
Stream.of(map.getOrDefault(e.getClassName(), e.getStudents()), e.getStudents())
.flatMap(List::stream)
.distinct()
.collect(Collectors.toList()),
(v1, v2) -> v2)
);
Output: Output:
{A=[name: Sam, age: 26, name: Aaron, age: 18, name: Peter, age: 40], B=[name: Daniel, age: 38, name: Eddy, age: 29, name: Ronnie, age: 33, name: Gabe, age: 35], C=[name: Fabian, age: 42, name: Edgar, age: 33], D=[name: Peter, age: 39, name: Calvin, age: 45]} {A=[姓名:Sam,年龄:26,姓名:Aaron,年龄:18,姓名:Peter,年龄:40],B=[姓名:Daniel,年龄:38,姓名:Eddy,年龄:29,姓名: Ronnie,年龄:33,姓名:Gabe,年龄:35],C=[姓名:Fabian,年龄:42,姓名:Edgar,年龄:33],D=[姓名:Peter,年龄:39,姓名:Calvin,年龄:45]}
You can do like this:你可以这样做:
public static List<ClassRoom> merge(List<ClassRoom> listA, List<ClassRoom> listB) {
Map<String, Set<Student>> map = new HashMap<>();
listA.forEach(item -> map.put(item.getClassName(), new HashSet<>(item.getStudents())));
for (ClassRoom classRoom : listB) {
Set<Student> set = map.getOrDefault(classRoom.getClassName(), new HashSet<>());
set.addAll(classRoom.getStudents());
map.put(classRoom.getClassName(), set);
}
List<ClassRoom> list = new ArrayList<>();
map.forEach((k, v) -> list.add(new ClassRoom(k, new ArrayList<>(v))));
return list;
}
and add below in Student:并在学生中添加以下内容:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Student)) return false;
Student student = (Student) o;
return getName() != null ? getName().equals(student.getName()) : student.getName() == null;
}
@Override
public int hashCode() {
return getName() != null ? getName().hashCode() : 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.