50

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

MyData {
    String name;
    boolean check;
} 

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

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

和 ListB 还包含

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

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

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

ListB包含

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

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

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

4

15 回答 15

52

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

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 语句必须是有条件的。上面的代码已更新。

于 2013-04-25T08:25:57.900 回答
18

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

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

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

编辑

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

于 2013-04-25T06:23:15.297 回答
6

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

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; 

    }

已编辑:-
我们如何涵盖这一点...想象一下,如果您有两个数组“A”,真“B”,真“C”,真和“A”,真“B”,真“D”,真。即使数组 1 有 C 并且数组 2 有 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; 

    }
于 2013-04-25T06:42:45.513 回答
2

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

于 2014-12-07T07:03:56.410 回答
2

首先,实现MyData.equals(Object o)andMyData.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;
于 2013-04-25T06:26:57.217 回答
1

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

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

于 2014-02-25T13:19:46.443 回答
1

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

于 2013-04-25T06:21:06.183 回答
1

这可以通过 Java8 使用 forEach 和 removeIf 方法轻松完成。

拿两张清单。从listA迭代并比较listB 中的元素

在removeIf方法中写入任何条件。

希望这会有所帮助

listToCompareFrom.forEach(entity -> listToRemoveFrom.removeIf(x -> x.contains(entity)));
于 2020-05-15T11:13:28.760 回答
1

使用 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();
}
于 2017-03-29T06:45:04.633 回答
0

看看这是否有效。

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;
    }
} 
于 2013-04-25T06:56:39.357 回答
0

逻辑应该是这样的:

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

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

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

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

于 2013-04-25T06:27:30.787 回答
0

从那时起已经过去了大约 5 年,幸运的是我们现在有了 Kotlin。
现在比较两个列表看起来很简单:

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

或者只是随意省略它并使用相等运算符。

于 2017-12-26T09:21:37.997 回答
0
String myData1 = list1.toString();
String myData2 = list2.toString()

return myData1.equals(myData2);

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

比较字符串对我有用。另请注意,我在 MyData 类中重写了 toString() 方法。

于 2018-09-26T01:34:52.903 回答
0

我知道这是个老问题,但万一有人需要。我在我的应用程序中使用它并且效果很好。我用它来检查购物车是否已更改。

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;
}
于 2018-02-14T13:12:05.007 回答
0

如果其中一些是 HashSet 集合,我认为您可以对这两个列表进行排序并转换为 List。

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
}
于 2019-01-11T10:09:08.277 回答