J'ai deux listes, disons List1 et List2. Je dois supprimer des éléments de List2 si cela est déjà présent dans List1
Pour éviter ConCurrentModificationException, j'ai essayé avec ListIterator
java.util.NoSuchElementException
J'obtiens l'exception ci-dessous dans la condition if
employeeList1 // data present employeeList2 // data present ListIterator<Employee> zeroList=employeeList2.listIterator(); //remove employee if already present in list1 while(zeroList.hasNext()){ for(Employee employee : employeeList1){ if(zeroList.next().getID().equals(employee.getId())){ zeroList.remove(); } } }
Il est possible que l'élément ne soit pas présent dans List1, mais la vérification de la condition est nécessaire.
4 Réponses :
Vous pouvez utiliser la méthode removeAll
sur la collection dont vous souhaitez supprimer les éléments et transmettre la collection en tant qu'arguments contenant les éléments que vous souhaitez supprimer.
static class Employee { private long employeeId; private String name; // whatever more variables public Employee(long employeeId, String name) { this.employeeId = employeeId; this.name = name; } public String toString() { return String.format("Employee[employeeId=%s, name=%s]", employeeId, name); } @Override public boolean equals(Object o) { if (o instanceof Employee) { return this.employeeId == ((Employee) o).employeeId; } return false; } @Override public int hashCode() { return new Long(employeeId).hashCode(); } } public static void main(String[] args) throws Exception { List<Employee> list1 = new ArrayList<>(); list1.add(new Employee(1, "a")); list1.add(new Employee(2, "b")); list1.add(new Employee(3, "c")); List<Employee> list2 = new ArrayList<>(); list2.add(new Employee(1, "a")); list2.add(new Employee(4, "d")); list2.add(new Employee(5, "e")); list2.removeAll(list1); System.out.println(list2); }
Supprime a
de la liste2 tel qu'il était présent dans la liste1 et affiche uniquement p
et q
,
[p, q]
Edit: Voici un exemple de code pour la classe Employee
alors que le vôtre peut être différent, mais comme vous l'avez dit, votre clé est employeeId
donc equals
et les méthodes hashCode
ne doivent jouer que sur employeeId
.
List<String> list1 = new ArrayList<>(); list1.add("a"); list1.add("b"); list1.add("c"); List<String> list2 = new ArrayList<>(); list2.add("a"); list2.add("p"); list2.add("q"); list2.removeAll(list1); System.out.println(list2);
Essayez d'utiliser ce code et voyez ce qu'il imprime, puis commentez simplement les méthodes equals
et hashCode
, puis voyez ce qui se passe. Après avoir commenté ces deux méthodes, l'objet présent dans list1 ne sera pas supprimé car list ne sait pas quand les deux objets sont égaux.
L'entité Mon employé contient plusieurs variables. Donc, la suppression via objet peut ne pas fonctionner toujours. Je dois supprimer en fonction de EmployeeId
Vous pouvez toujours utiliser la même méthode même si votre liste stocke un objet personnalisé. Assurez-vous simplement d'implémenter les méthodes equals()
et hashCode()
dans votre classe dont l'objet est stocké dans votre liste. Et comme vous le dites en fonction de employeeId, implémentez simplement vos deux méthodes equals
et hashCode
basées sur employeeId
Pouvez-vous ajouter le code de votre classe personnalisée dans votre message? Je vous donnerai alors des conseils spécifiques.
Est-il nécessaire de remplacer le hashcode puisque j'utilise arraylist ici
petite confusion ici ... Je dois supprimer "a" uniquement de la liste 2, pas de la liste 1. Signifie que les données présentes dans la liste 1 doivent être supprimées de la liste2
Désolé pour la petite confusion. Remplacer uniquement la méthode equals()
devrait être suffisant car vous n'utilisez aucun HashMap
ou HashSet
qui utilise effectivement la hashCode()
. Mais en général, il est recommandé de toujours implémenter à la fois equals
et hashCode
afin que si l'objet est utilisé quelque part comme clé dans une structure de données de hachage, il se comporte bien et de manière cohérente.
@RoseyKhatun: Mon exemple de code ci-dessus dans ma réponse supprime exactement a
de list2 car a
est également contenu dans list1
. list1 a ab et c et list2 a apq donc quand vous supprimez le contenu de list1 de list2, juste a
est supprimé et list2 reste avec p
et q
seulement.
Quel est le problème avec le plus simple
List<Employee> employeeList1 List<Employee> employeeList2 for (Employee employee : employeeList2) { if (employeeList1.contains(employee)) { employeeList2.remove(employee) } }
Bien sûr, vous devrez synchroniser les appels de liste si vous utilisez plusieurs threads.
L'entité Mon employé contient plusieurs variables. Donc, la suppression via objet peut ne pas fonctionner toujours. Je dois supprimer en fonction de EmployeeId
Et si vous implémentez Employee.equals () d'une manière que employee1.equals (employee2) si les employeeIds sont égaux? Ou avez-vous besoin d'une autre égalité ailleurs?
Vous pouvez utiliser les collections communes Apache
bibliothèque:
List<String> newList = ListUtils.union(list1, list2);
employeeList1 // data present employeeList2 // data present List<Employee> newList = new ArrayList<Empolyee>(); newList.add(employeeList2 ); newList.retainAll(employeeList1); newList will not contain the employeeList1 data.
Bienvenue à SO! Bien que cela résout presque le problème, pourriez-vous s'il vous plaît expliquer ce que fait votre code pour que même un utilisateur inexpérimenté puisse le comprendre? Merci!