Java 中的列表中添加多个 NULL

Multiple NULL addition into a List in Java

我有 2 个列表,想将一些元素从一个列表复制到另一个列表,即有新旧员工列表我需要联合 2 个列表并删除包含在旧列表中但不包含在新列表中的元素一.

我可以通过使用 TreeSet 并覆盖 Employees 的 equals 和 hashcode 函数来解决获取并集和交集的部分 class...

现在,我想排除旧元素而不是新元素并将它们添加到 "deletedList"...我得到 "ConcurrentModificationException"

我试过这个而不是 "iterator" 但结果相同:for(Employees e : employeesListDB)

我也试过 "CopyOnWriteArrayList" 而不是 "ArrayList" 但没有改变!!

但是现在的问题是在初始化空列表时"deletedList"它在add函数之前填充了多个空元素!

代码如下:

List<Employees> employeesListDB = this.findAll();     

Set<Employees> empSet = new TreeSet<Employees>(new EmployeeComparator());
empSet.addAll(employeesList);

List<Employees> deletedList = new ArrayList<Employees>();
Employees e = new Employees();

ListIterator<Employees> itr = employeesListDB.listIterator();    
for(itr.hasNext()) { 
  e = (Employees)itr.next();
  if(!empSet.contains(e)) {
    deletedList.add(e);
  }               
}

一个计数器示例:

旧列表"employeesListDB" 数据库中的员工列表:

[  
    {  
        "email":"mariam.moustafa@x.com"
    },
    {  
        "email":"sara.ahmed@x.com"
    },
    {  
        "email":"ali.hassan@x.com"
    },
    {  
        "email":"hoosen.imam-ally@x.com"
    },
    {  
        "email":"allan.randall@x.com"
    },
    {  
        "email":"nishaan.maharaj@x.com"
    }
]

要添加的新列表:

[  
    {  
        "email":"ali.moustafa@x.com"
    },
    {  
        "email":"sara.ahmed@x.com"
    },
    {  
        "email":"emad.hamed@x.com"
    }  

]

我要删除的列表:

[
{
"email":"mariam.moustafa@x.com" }, {
"email":"ali.hassan@x.com" }, {
"email":"hoosen.imam-ally@x.com" }, {
"email":"allan.randall@x.com" }, {
"email":"nishaan.maharaj@x.com" } ]

Sara 邮件即将更新...

Employee class 有两个字段 {id,email} 新列表(要添加到数据库的列表)是一个只有电子邮件的列表,id 字段尚未被识别,但旧列表有完整的 bean 字段 ...为了在这两个列表之间进行比较,我应该重写 Comparator 以忽略 id 字段;

只是我需要知道,为什么当我使用 set.add 操作时,它只添加唯一的电子邮件!列表的原始大小是 36 个元素,将其添加到集合中后变为只有 16 个!

 Set<Employees> oldSet = new TreeSet<Employees>(new EmployeeComparator());
        oldSet.addAll(employeesListDB);

        Set<Employees> newSet = new TreeSet<Employees>(new EmployeeComparator());
        newSet.addAll(employeesList);


        Set<Employees> deleted = Sets.difference(oldSet, newSet);

the empty list filled with multiple null elements before the add function!

这是因为您使用的 ArrayList 包含以下常量:

private static final int DEFAULT_CAPACITY = 10;

这意味着当您使用 new 运算符创建 ArrayList<T> 时,您实际上创建了 TArray,其中包含 10 个 null(它是包含为 private transient Object[] elementData 字段)。

JLS said:

Every variable in a program must have a value before its value is used:

Each class variable, instance variable, or array component is initialized with a default value when it is created (§15.9, §15.10.2):

[...]

For all reference types (§4.3), the default value is null.

据我了解,您需要所有包含在旧集合中但不包含在新集合中的元素。

为此,您可以使用 Guava Sets#difference 方法:

Set<Employees> deleted = Sets.difference(oldSet, newSet);

使用您的数据进行测试:

Set<String> oldEmployees = Sets.newHashSet("mariam.moustafa@x.com", "sara.ahmed@x.com", "ali.hassan@x.com", "hoosen.imam-ally@x.com", "allan.randall@x.com", "nishaan.maharaj@x.com");
Set<String> newEmployees = Sets.newHashSet("ali.moustafa@x.com", "sara.ahmed@x.com", "emad.hamed@x.com");

Set<String> diff = Sets.difference(oldEmployees, newEmployees);

System.out.println(diff);

结果:

[nishaan.maharaj@x.com, mariam.moustafa@x.com, ali.hassan@x.com, allan.randall@x.com, hoosen.imam-ally@x.com]

这是使用 2 个简单步骤的核心 Java 解决方案:

[1] - 创建一个集合 setOld 其中包含第一组电子邮件
[2] - 从 setOld 中减去一组新的电子邮件 setNew

Set oldSet<String> = new HashSet<String>();  // original set of email addresses
oldSet.add("mariam.moustafa@x.com");
oldSet.add("sara.ahmed@x.com");
oldSet.add("ali.hassan@x.com");
oldSet.add("hoosen.imam-ally@x.com");
oldSet.add("allan.randall@x.com");
oldSet.add("nishaan.maharaj@x.com");

Set newSet<String> = new HashSet<String>();  // new set of email addresses
newSet.add("ali.moustafa@x.com");
newSet.add("sara.ahmed@x.com");
newSet.add("emad.hamed@x.com");

for (String s : newSet) {
    oldSet.remove(s);     // this will only remove the element if found
}

// display new contents of oldSet
for (String s : oldSet) {
    System.out.println(s);
}

输出:

mariam.moustafa@x.com
ali.hassan@x.com
hoosen.imam-ally@x.com
allan.randall@x.com
nishaan.maharaj@x.com

这样试试(做了一个小的TestCase):

private static Employee createEmployee(String string) {
    Employee employee = new Employee();
    employee.setEmail(string);
    return employee;
}

public static void main(String[] args)  {

    List<String> newMails = new ArrayList<>();
    List<Employee> oldList = new ArrayList<>();

    oldList.add(createEmployee("mariam.moustafa@x.com"));
    oldList.add(createEmployee("sara.ahmed@x.com"));
    oldList.add(createEmployee("ali.hassan@x.com"));
    oldList.add(createEmployee("hoosen.imam-ally@x.com"));
    oldList.add(createEmployee("allan.randall@x.com"));
    oldList.add(createEmployee("nishaan.maharaj@x.com"));

    newMails.add("ali.moustafa@x.com");
    newMails.add("sara.ahmed@x.com");
    newMails.add("emad.hamed@x.com");

    List<Employee> delete = new ArrayList<>();
    Set<String> removedMails = new HashSet<>();

    for (Employee emp : oldList) {
        if (!newMails.contains(emp.getEmail())) {
            delete.add(emp);
        }
        removedMails.add(emp.getEmail());
    }
    newMails.removeAll(removedMails);
    // remove emploeyees in delete
    oldList.removeAll(delete);

    // Create employee for left MAils
    for (String newMail : newMails) {
        oldList.add(createEmployee(newMail));
    }

    //Old and new Employees
    for (Employee emp : oldList) {
        System.out.println(emp.getEmail());
    }

}

普通员工class:

class Employee {
String email;

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

}

输出:

sara.ahmed@x.com
ali.moustafa@x.com
emad.hamed@x.com

使用 List removeAll 方法。 您将需要覆盖 Employees class 中的 equals 方法。基于员工 ID 的 PFB 示例片段,您需要修改它以适应基于电子邮件 ID:

import java.util.*;

public class StringArray {

    public static void main(String args[]) {

        List<Employee> oldList = new ArrayList<Employee>();
        oldList.add(new Employee(1));
        oldList.add(new Employee(2));
        oldList.add(new Employee(3));
        oldList.add(new Employee(4));

        List<Employee> newList = new ArrayList<Employee>();
        newList.add(new Employee(3));
        newList.add(new Employee(4));
        newList.add(new Employee(5));
        newList.add(new Employee(6));

        oldList.removeAll(newList);

        System.out.println("Printing delete list");
        for (Employee employee : oldList)
            System.out.println(employee);

        System.out.println("Printing updated list");
        for (Employee employee : newList)
            System.out.println(employee);
    }
}

public class Employee {
    private int id; 

    public Employee(int id) {
        super();
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Employee [id=" + this.id + "]";
    }

    @Override
    public boolean equals(Object o) {       

        if (o == this)
            return true;        

        if (!(o instanceof Employee)) 
            return false; 

        Employee c = (Employee) o;         

        return this.id == c.id;     
    }   
}