3
votes

Comment supprimer un élément d'une liste en comparant deux listes

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.


0 commentaires

4 Réponses :


2
votes

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.


6 commentaires

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.



0
votes

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.


2 commentaires

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?



0
votes

Vous pouvez utiliser les collections communes Apache

bibliothèque:

List<String> newList = ListUtils.union(list1, list2);


0 commentaires

0
votes
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.

1 commentaires

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!