【问题标题】:Add or Update elements of an ArrayList based on another ArrayList基于另一个 ArrayList 添加或更新 ArrayList 的元素
【发布时间】:2021-06-24 01:57:41
【问题描述】:

我有两个 ClassRoom 对象的 ArrayList,下面显示了 ClassRoom 类:

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 类包含 className 字符串属性和Student 对象列表,描述如下:

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

}

我创建了两个ClassRoom 对象列表,如下所示:

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

所以我的最终任务是创建一个新的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}]}
   */
}

下面解释我的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;
 }

到目前为止,我遇到的问题是在合并方法调用后产生了一个空列表。任何建议将不胜感激。

【问题讨论】:

  • this 可以得到帮助。而且您不需要在collect 中同时创建forEach 循环

标签: java list arraylist java-8


【解决方案1】:
  1. name 上覆盖Student 中的equalshashCode 方法。
@Override
public boolean equals(Object obj) {
    return Objects.equals(name, ((Student) obj).getName());
}

@Override
public String toString() {
    return "name: " + name + ", age: " + age;
}
  1. 使用 IDE 建议的默认实现覆盖 ClassRoom 中的 equalshashCode 方法。
  2. list2收集到Map&lt;String, List&lt;Student&gt;&gt; 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)
                            );

输出:

{A=[姓名:Sam,年龄:26,姓名:Aaron,年龄:18,姓名:Peter,年龄:40], B=[姓名:Daniel,年龄:38,姓名:Eddy,年龄:29,姓名:Ronnie,年龄:33, 姓名:Gabe,年龄:35],C=[姓名:Fabian,年龄:42,姓名:Edgar,年龄:33], D=[姓名:彼得,年龄:39,姓名:卡尔文,年龄:45]}

ONLINE DEMO

【讨论】:

    【解决方案2】:

    你可以这样做:

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

    并在学生中添加以下内容:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-20
      • 2017-01-11
      • 1970-01-01
      相关资源
      最近更新 更多