web-dev-qa-db-fra.com

Les valeurs des objets Java Compare Two List?

J'ai deux listes * *ListA<MyData> listA = new ArrayList<MyData>() ** et ListB<MyData> listB = new ArrayList<MyData>() _ tous deux contiennent un objet de type MyData et MyData _ contiennent ces variables.

MyData {
    String name;
    boolean check;
} 

ListA et ListB contiennent tous deux des objets MyData, je dois maintenant comparer les valeurs d'objet de la liste ici nom ainsi que vérification variable comme si ListA contient ces valeurs d'objet

ListA = ["Ram",true],["Hariom",true],["Shiv",true];

et ListB contiennent également

ListB = ["Ram",true],["Hariom",true],["Shiv",true];

alors je dois comparer les listes et renvoyer false car les deux listes sont identiques, mais si ListA contient

ListA = ["Ram",true],["Hariom",true],["Shiv",false];

et ListB Contain

 ListB = ["Ram",true],["Hariom",true],["Shiv",true];

alors je dois comparer les listes et retourner vrai parce que les deux listes ne sont pas identiques

ou vice-versa, donc toute légère modification dans les valeurs de liste quelconques doit être vraie. Une chose que je dois mentionner ici, les objets peuvent être dans n'importe quel ordre.

34
user2309806

J'ai cette solution pour le problème ci-dessus 

public boolean compareLists(List<MyData> prevList, List<MyData> modelList) {
        if (prevList.size() == modelList.size()) {
            for (MyData modelListdata : modelList) {
                for (MyData prevListdata : prevList) {
                    if (prevListdata.getName().equals(modelListdata.getName())
                            && prevListdata.isCheck() != modelListdata.isCheck()) {
                        return  true;

                    }
                }

            }
        }
        else{
            return true;
        }
        return false; 

    }

Édité: -  
Comment pouvons-nous couvrir cela .... Imaginez si vous aviez deux tableaux "A", vrais "B", vrais "C", vrais et "A", vrais "B", vrais "D", vrai. Même si le tableau un a le C et le tableau deux le D, il n'y a pas de contrôle qui puisse le détecter (Mentionné par @Patashu) .. SO, j'ai donc apporté des modifications ci-dessous.

public boolean compareLists(List<MyData> prevList, List<MyData> modelList) {
        if (prevList!= null && modelList!=null && prevList.size() == modelList.size()) {
            boolean indicator = false;
            for (MyData modelListdata : modelList) {
                for (MyData prevListdata : prevList) {
                    if (prevListdata.getName().equals(modelListdata.getName())
                            && prevListdata.isCheck() != modelListdata.isCheck()) {
                        return  true;

                    }
                    if (modelListdata.getName().equals(prevListdata.getName())) {
                        indicator = false;
                        break;
                    } else
                        indicator = true;
                }
                }

            }
        if (indicator)
            return true;
    }
        }
        else{
            return true;
        }
        return false; 

    }
5
user2309806

Ce n'est pas la solution la plus efficace, mais le code le plus laconique serait:

boolean equalLists = listA.size() == listB.size() && listA.containsAll(listB);

Mettre à jour:

@WesleyPorter a raison. La solution ci-dessus ne fonctionnera pas si des objets en double se trouvent dans la collection.
Pour une solution complète, vous devez parcourir une collection afin que les objets en double soient gérés correctement.

private static boolean cmp( List<?> l1, List<?> l2 ) {
    // make a copy of the list so the original list is not changed, and remove() is supported
    ArrayList<?> cp = new ArrayList<>( l1 );
    for ( Object o : l2 ) {
        if ( !cp.remove( o ) ) {
            return false;
        }
    }
    return cp.isEmpty();
}

Mise à jour du 28 octobre 2014:

@ RoeeGavriel a raison. La déclaration de retour doit être conditionnelle. Le code ci-dessus est mis à jour.

38
Oded Peer

ArrayList a déjà un support pour cela, avec la méthode equals. Citant les docs

... En d'autres termes, deux listes sont définies égales si elles contiennent les mêmes éléments dans le même ordre.

Cela nécessite que vous implémentiez correctement equals dans votre classe MyData.

Modifier 

Vous avez mis à jour la question en indiquant que les listes pourraient avoir des ordres différents. Dans ce cas, commencez par trier votre liste, puis appliquez equals.

12
NilsH

Tout d’abord, implémentez les méthodes MyData.equals(Object o) et MyData.hashCode() . Une fois que vous avez implémenté la méthode equals, vous pouvez effectuer une itération sur les listes comme suit:

if(ListA == null && ListB == null)
    return false;
if(ListA == null && ListB != null)
    return true;
if(ListA != null && ListB == null)
    return true;
int max = ListA.size() > ListB.size() ? ListA.size() : ListB.size();
for(int i = 0; i < max; i++) {
    myData1 = ListA.get(i);
    myData2 = ListB.get(i);
    if(!myData1.equals(myData2)) {
        return true;
    }
}
return false;
2
Amir Kost

Utilisation de Java 8 removeIf pour comparer des éléments similaires

public int getSimilarItems(){
    List<String> one = Arrays.asList("milan", "dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta");
    List<String> two = new ArrayList<>(Arrays.asList("hafil", "iga", "binga", "mike", "dingo")); //Cannot remove directly from array backed collection
    int initial = two.size();

    two.removeIf(one::contains);
    return initial - two.size();
}
1
Asanka Siriwardena

Voir si cela fonctionne.

import Java.util.ArrayList;
import Java.util.List;


public class ArrayListComparison {

    public static void main(String[] args) {
        List<MyData> list1 = new ArrayList<MyData>();
        list1.add(new MyData("Ram", true));
        list1.add(new MyData("Hariom", true));
        list1.add(new MyData("Shiv", true));
//      list1.add(new MyData("Shiv", false));
        List<MyData> list2 = new ArrayList<MyData>();
        list2.add(new MyData("Ram", true));
        list2.add(new MyData("Hariom", true));
        list2.add(new MyData("Shiv", true));

        System.out.println("Lists are equal:" + listEquals(list1, list2));
    }

    private static boolean listEquals(List<MyData> list1, List<MyData> list2) {
        if(list1.size() != list2.size())
            return true;
        for (MyData myData : list1) {
            if(!list2.contains(myData))
                return true;
        }
        return false;
    }
}

class MyData{
    String name;
    boolean check;


    public MyData(String name, boolean check) {
        super();
        this.name = name;
        this.check = check;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + (check ? 1231 : 1237);
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        MyData other = (MyData) obj;
        if (check != other.check)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
} 
1
krishnakumarp

J'ai trouvé un exemple très basique de comparaison de liste dans Comparaison de liste Cet exemple vérifie d'abord la taille, puis la disponibilité de l'élément particulier d'une liste dans une autre.

1
Manoj Kumar
String myData1 = list1.toString();
String myData2 = list2.toString()

return myData1.equals(myData2);

where :
list1 - List<MyData>
list2 - List<MyData>

Comparer la chaîne a fonctionné pour moi. De plus, NOTE j'avais remplacé la méthode toString () dans la classe MyData.

0
abc123

Je pense que vous pouvez trier les deux listes et les convertir en liste si certaines d'entre elles étaient une collection HashSet.

Java.utils.Collections package vous permet de le faire.

List<Category> categoriesList = new ArrayList<>();
Set<Category> setList = new HashSet<>();
Collections.sort(categoriesList);
List<Category> fileCategories = new ArrayList<>(setList);
Collections.sort(fileCategories);

if(categoriesList.size() == fileCategories.size() && categoriesList.containsAll(fileCategories)) {
    //Do something
}
0
Sky Games Inc

Je sais que c'est une vieille question, mais au cas où quelqu'un en aurait besoin. Je l'utilise dans mon application et cela fonctionne bien. Je l'ai utilisé pour vérifier si le panier a été changé ou non. 

private boolean validateOrderProducts(Cart cart) {
    boolean doesProductsChanged = false;
    if (originalProductsList.size() == cart.getCartItemsList().size()) {
        for (Product originalProduct : originalProductsList) {
            if (!doesProductsChanged) {
                for (Product cartProduct : cart.getCartProducts()) {
                    if (originalProduct.getId() == cartProduct.getId()) {
                        if (originalProduct.getPivot().getProductCount() != cartProduct.getCount()) {
                            doesProductsChanged = true;
                            // cart has been changed -> break from inner loop
                            break;
                        }
                    } else {
                        doesProductsChanged = false;
                    }
                }
            } else {
                // cart is already changed -> break from first loop
                break;
            }
        }
    } else {
        // some products has been added or removed (simplest case of Change)
        return true;
    }
    return doesProductsChanged;
}
0
mohnage7

Remplacez la méthode equals dans votre classe et utilisez Collection # equals () pour vérifier l’égalité.

0
NINCOMPOOP

Cela fait environ 5 ans depuis et, heureusement, nous avons maintenant Kotlin.
La comparaison de deux listes à présent est aussi simple que:

fun areListsEqual(list1 : List<Any>, list2 : List<Any>) : Boolean {
        return list1 == list2
}

Ou simplement vous sentir libre de l'omettre du tout et d'utiliser l'opérateur d'égalité.

0
Leo Droidcoder

La logique devrait être quelque chose comme:

  1. Première étape: pour la classe, MyData implémente une interface comparable, substituez la méthode compareTo selon les besoins de chaque objet.

  2. Deuxième étape: quand il s’agit de comparer les listes (après vérification des valeurs nulles), 2.1 Vérifier la taille des deux listes, si égal renvoie vrai, sinon retourne, retourne à l’objet itération 2.2 Si l’étape 2.1 renvoie vrai, itéré sur les éléments des deux listes et invoquer quelque chose comme, 

    listA.get (i) .compareTo (listB.get (i))

Ce sera selon le code mentionné à l'étape 1.

0
Himanshu Bhardwaj

Vous pouvez soustraire une liste de l'autre à l'aide de CollectionUtils.subtract. Si le résultat est une collection vide, cela signifie que les deux listes sont identiques. Une autre approche consiste à utiliser CollectionUtils.isSubCollection ou CollectionUtils.isProperSubCollection.

Dans tous les cas, vous devez implémenter les méthodes equals et hashCode pour votre objet.

0
Luiz Feijão Veronesi