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>
时,您实际上创建了 T
的 Array
,其中包含 10 个 null
(它是包含为 private transient Object[] elementData
字段)。
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;
}
}
我有 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>
时,您实际上创建了 T
的 Array
,其中包含 10 个 null
(它是包含为 private transient Object[] elementData
字段)。
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;
}
}