Java 比较两个列表的对象值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16207718/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 05:47:56  来源:igfitidea点击:

Java Compare Two List's object values?

javalistarraylist

提问by

I have two list **ListA<MyData> listA = new ArrayList<MyData>()** and ListB<MyData> listB = new ArrayList<MyData>()both contain object of type MyDataand MyDatacontain these variables.

我有两个列表* *ListA<MyData> listA = new ArrayList<MyData>()**和ListB<MyData> listB = new ArrayList<MyData>()都包含类型的对象迈德特迈德特包含这些变量。

MyData {
    String name;
    boolean check;
} 

ListA and ListB both contains MyData objects ,now I have to compare both the list's object values here nameas well checkvariable like if ListAcontains these object values

ListA 和 ListB 都包含 MyData 对象,现在我必须在此处比较两个列表的对象值名称以及检查变量,例如ListA 是否包含这些对象值

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

and ListB also contain

和 ListB 还包含

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

then i have to compare lists and return false because both list are same But if ListA contains

然后我必须比较列表并返回 false 因为两个列表是相同的但是如果 ListA 包含

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

and ListBContain

ListB包含

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

then I have to compare lists and return true because both list are not same

然后我必须比较列表并返回 true,因为两个列表都不相同

or vice-versa so any slight change in the any list values I have to return true. One thing I have to mentioned here objects can be in any order.

反之亦然,因此任何列表值的任何细微变化我都必须返回true。 我必须在这里提到的一件事对象可以按任何顺序排列。

采纳答案by Himanshu Bhardwaj

I got this solution for above problem

我得到了上述问题的解决方案

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; 

    }

EDITED:-
How can we cover this... Imagine if you had two arrays "A",true "B",true "C",true and "A",true "B",true "D",true. Even though array one has C and array two has D there's no check that will catch that(Mentioned by @Patashu)..SO for that i have made below changes.

编辑:-
我们如何涵盖这个......想象一下,如果你有两个数组“A”,真“B”,真“C”,真和“A”,真“B”,真“D”,真。即使数组一有 C 数组二有 D 也没有检查可以捕捉到(@Patashu 提到)..所以我做了以下更改。

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; 

    }

回答by NINCOMPOOP

Override the equalsmethod in your class and use Collection#equals()method to check for equality.

覆盖类中的equals方法并使用 Collection#equals()方法来检查相等性。

回答by NilsH

ArrayListalready have support for this, with the equalsmethod. Quoting the docs

ArrayList已经有了对此的支持,使用equals方法。引用文档

... In other words, two lists are defined to be equal if they contain the same elements in the same order.

... 换句话说,如果两个列表以相同的顺序包含相同的元素,则它们被定义为相等。

It does require you to properly implement equalsin your MyDataclass.

它确实需要您equalsMyData课堂上正确实施。

Edit

编辑

You have updated the question stating that the lists could have different orders. In that case, sort your list first, and then apply equals.

您已更新问题,指出列表可能具有不同的顺序。在这种情况下,首先对您的列表进行排序,然后应用等于。

回答by Amir Kost

First, implement the MyData.equals(Object o)and MyData.hashCode()methods. Once you implemented the equalsmethod, you can iterate over the lists as follows:

首先,实现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;

回答by Himanshu Bhardwaj

Logic should be something like:

逻辑应该是这样的:

  1. First step: For class MyData implements Comparable interface, override the compareTo method as per the per object requirement.

  2. Second step: When it comes to list comparison (after checking for nulls), 2.1 Check the size of both lists, if equal returns true else return false, continue to object iteration 2.2 If step 2.1 returns true, iterate over elements from both lists and invoke something like,

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

  1. 第一步:对于类 MyData 实现 Comparable 接口,根据每个对象的要求覆盖 compareTo 方法。

  2. 第二步:进行列表比较时(检查空值后), 2.1 检查两个列表的大小,如果相等返回真否则返回假,继续对象迭代 2.2 如果步骤 2.1 返回真,则迭代两个列表中的元素并调用类似的东西,

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

This will be as per the code mentioned in step-1.

这将按照步骤 1 中提到的代码进行。

回答by krishnakumarp

See if this works.

看看这是否有效。

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

回答by Oded Peer

It's not the most efficient solution but the most terse code would be:

这不是最有效的解决方案,但最简洁的代码是:

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

Update:

更新:

@WesleyPorter is right. The solution above will not work if duplicate objects are in the collection.
For a complete solution you need to iterate over a collection so duplicate objects are handled correctly.

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

Update 28-Oct-2014:

2014 年 10 月 28 日更新:

@RoeeGavriel is right. The return statement needs to be conditional. The code above is updated.

@RoeeGavriel 是对的。return 语句需要有条件。上面的代码已更新。

回答by Luiz Feij?o Veronesi

You can subtract one list from the other using CollectionUtils.subtract, if the result is an empty collection, it means both lists are the same. Another approach is using CollectionUtils.isSubCollection or CollectionUtils.isProperSubCollection.

您可以使用 CollectionUtils.subtract 从另一个列表中减去一个列表,如果结果是一个空集合,则表示两个列表相同。另一种方法是使用 CollectionUtils.isSubCollection 或 CollectionUtils.isProperSubCollection。

For any case you should implement equals and hashCode methods for your object.

在任何情况下,您都应该为您的对象实现 equals 和 hashCode 方法。

回答by Manoj Kumar

I found a very basic example of List comparison at List CompareThis example verifies the size first and then checks the availability of the particular element of one list in another.

我在List Compare找到了一个非常基本的 List 比较 示例 这个示例首先验证大小,然后检查一个列表中特定元素在另一个列表中的可用性。

回答by Asanka Siriwardena

Using java 8 removeIf to compare similar items

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