web-dev-qa-db-ja.com

Java 2つのリストのオブジェクト値を比較しますか?

2つのリスト* *ListA<MyData> listA = new ArrayList<MyData>() **とListB<MyData> listB = new ArrayList<MyData>()があり、両方ともMyDataMyDataのタイプのオブジェクトが含まれ、これらの変数が含まれています。

MyData {
    String name;
    boolean check;
} 

ListAとListBの両方にMyDataオブジェクトが含まれているため、ここで両方のリストのオブジェクト値を比較する必要がありますname同様にcheck if ListAはオブジェクト値

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

およびListBも含まれています

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

その後、リストを比較し、両方のリストが同じであるためfalseを返す必要があります

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

およびListB含む

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

両方のリストが同じではないため、リストを比較してtrueを返す必要があります

またはその逆であるため、trueを返す必要があるリスト値のわずかな変更。 ここでオブジェクトについて言及しなければならないことの1つは、任意の順序である可能性があります。

41
user2309806

上記の問題に対するこの解決策を得た

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; 

    }

編集済み:-
これをどのようにカバーできますか... 2つの配列 "A"、true "B"、true "C"、trueおよび "A"、true "B"、true "D"、trueがある場合を想像してください。配列1にはCがあり、配列2にはDがありますが、それをキャッチするチェックはありません(メンション:@Patashu).. SO以下の変更。

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

これは最も効率的なソリューションではありませんが、最も簡潔なコードは次のとおりです。

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

更新:

@WesleyPorterは正しい。重複オブジェクトがコレクション内にある場合、上記のソリューションは機能しません。
完全なソリューションを実現するには、コレクションを反復処理して、重複オブジェクトが正しく処理されるようにする必要があります。

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();
}

2014年10月28日更新:

@RoeeGavrielは正しい。 returnステートメントは条件付きである必要があります。上記のコードが更新されます。

41
Oded Peer

ArrayListメソッドを使用して、equalsは既にこれをサポートしています。引用 ドキュメント

...つまり、2つのリストは、同じ要素が同じ順序で含まれている場合に等しいと定義されます。

equalsクラスにMyDataクラスを適切に実装する必要があります。

編集

リストの順序が異なる可能性があることを示す質問を更新しました。その場合は、リストを最初にソートしてから、等しいを適用します。

14
NilsH

最初に、MyData.equals(Object o)およびMyData.hashCode()メソッドを実装します。 equalsメソッドを実装したら、次のようにリストを反復処理できます。

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

Java 8 removeIfを使用して同様のアイテムを比較する

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

これが機能するかどうかを確認します。

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

List Compare でリスト比較の非常に基本的な例を見つけました。この例では、最初にサイズを検証してから、あるリストの特定の要素の可用性を別のリストで確認します。

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

return myData1.equals(myData2);

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

文字列の比較は私のために働いた。また、MyDataクラスでtoString()メソッドをオーバーライドしました。

0
abc123

両方のリストをソートして、そのうちのいくつかがHashSetコレクションである場合はリストに変換できると思います。

Java.utils.Collectionsパッケージでそれを実行できます。

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

私はそれが古い質問であることを知っていますが、誰かがそれを必要とする場合に備えて。私は自分のアプリケーションでこれを使用し、うまく機能しています。カートが変更されたかどうかを確認するために使用しました。

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

クラスで equals メソッドをオーバーライドし、 Collection#equals() メソッドを使用して同等性を確認します。

0
NINCOMPOOP

それから約5年が経ちましたが、幸運なことに、今ではコトリンがあります。
2つのリストの外観の比較は、次のように簡単になりました。

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

または、それをまったく省略して、等号演算子を使用することもできます。

0
Leo Droidcoder

ロジックは次のようになります。

  1. 最初のステップ:クラスMyDataがComparableインターフェースを実装する場合、オブジェクトごとの要件に従ってcompareToメソッドをオーバーライドします。

  2. 2番目のステップ:リストの比較(ヌルのチェック後)で、2.1両方のリストのサイズをチェックし、等しい場合はtrueを返し、そうでない場合はfalseを返し、2.2を繰り返します。ステップ2.1がtrueを返した場合、何かを呼び出す、

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

これは、手順1で述べたコードのとおりです。

0

CollectionUtils.subtractを使用して一方のリストを他方から減算できます。結果が空のコレクションである場合、両方のリストが同じであることを意味します。別のアプローチは、CollectionUtils.isSubCollectionまたはCollectionUtils.isProperSubCollectionを使用することです。

いずれの場合も、オブジェクトにequalsメソッドとhashCodeメソッドを実装する必要があります。