Java ArrayList:contains()方法在ArrayList包含给定对象时返回false
我对Java ArrayList:contains()方法在ArrayList包含给定对象时返回false,java,arrays,arraylist,contains,evaluation,Java,Arrays,Arraylist,Contains,Evaluation,我对contains()方法有问题,该方法返回false,即使ArrayList包含给定的对象。 我的代码如下: String [] transaction = dbConnection.getPendingTransaction(username); if (!onlineConnection.getSentTransactionRequests().contains(transaction)) { onlineConnection.getSentTransactionRequests
contains()
方法有问题,该方法返回false,即使ArrayList
包含给定的对象。
我的代码如下:
String [] transaction = dbConnection.getPendingTransaction(username);
if (!onlineConnection.getSentTransactionRequests().contains(transaction)) {
onlineConnection.getSentTransactionRequests().add(transaction);
String packet = "RTR" + "_" + transaction[0] + "_" + transaction[2] +
"_" + transaction[3] + "_" + transaction[4];
onlineConnection.send(packet);
}
我在迭代之间尝试了Thread.sleep()
,因此ArrayList
并没有被如此急切地加载,但没有成功。这是因为String[]transaction
是对象。当您调用contains
时,列表使用equals
方法将新对象与其他对象进行比较。想象一下这样做
new Object().equals(new Object())
如果getPendingTransaction和getSentTransactionRequests应该返回相同的数组,而不是创建新数组,请查看它们。第二,尝试调试并查找数组对象id。如果这不相同,但应该相同(并且包含相同的元素),请尝试解决这一问题(例如创建比较器或列表或类似内容)。数组的hashCode()
和equals()
在这方面有点混乱(这是一个漫长而不同的讨论)
一种可能的解决方法是使用ArrayList
而不是ArrayList
,ArrayList
的equals()
方法将与您期望的一样
例如:
ArrayList<String> l1 = new ArrayList<>();
ArrayList<String> l2 = new ArrayList<>();
l1.add("asdf");
l2.add("asdf");
ArrayList<ArrayList<String>> coll = new ArrayList<>();
coll.add(l1);
System.out.println(coll.contains(l2));
ArrayList l1=新的ArrayList();
ArrayList l2=新的ArrayList();
l1.添加(“asdf”);
l2.添加(“asdf”);
ArrayList coll=新的ArrayList();
coll.add(l1);
System.out.println(coll.contains(l2));
将产生true
,正如预期的那样问题在于数组的equals
定义为引用相等。换句话说,根据equals
方法,包含相同元素的两个不同数组不相等
如果希望“transaction”对象的equals
基于字符串的相等性,则需要创建一个自定义类来保存字符串[]
,并重写equals
方法和hashcode
方法
顺便说一句,arrayequals(Object)
方法并不是“有点破绽”。定义的equals
语义只是反映了一个事实,即任何数组对象本身都是可变的。如果您必须使用列表
,那么您可能是运气不好,没有使用equals()
或hashCode()
也许你们最好创建一个方法来比较你们的对象
差不多
public static boolean stringArrayListEquals(List<String[]> list, List<String[]> list2) {
if (list.size() != list2.size()) return false;
for (int i = 0; i < list.size(); ++i){
if (!Arrays.equals(list.get(i), list2.get(i)) return false;
}
return true;
}
公共静态布尔StringArrayListQuals(列表,列表2){
if(list.size()!=list2.size())返回false;
对于(int i=0;i
要测试contains()
,您需要另一个循环
尽管你应该认真地使用列表
。我也遇到过类似的问题。我只是写了以下代码片段:
assertContains(list, toLookFor); // To call the below private method
private void assertContains(ArrayList<String> list, String toLookFor) {
String arrayListToString = rulesList.toString();
if (arrayListToString.contains(toLookFor))
System.out.println("The list contains "+ toLookFor);
else
System.out.println("The list does not contains "+ toLookFor);
}
assertContains(list,toLookFor);//调用下面的私有方法
私有void资产内容(ArrayList,字符串toLookFor){
字符串arrayListToString=rulesList.toString();
if(arrayListToString.contains(toLookFor))
System.out.println(“列表包含”+toLookFor);
其他的
System.out.println(“列表中不包含“+toLookFor”);
}
equals
和hashcode
显然不是您的朋友。请,请,请,请将您的事务建模为一个适当的对象,而不是字符串数组。然后查看上面@haylem的注释。不完全正确,请注意,如果集合包含“asdf”,并且您检查了list.contains(新字符串(“asdf”))
你会明白的。@amit谢谢你。更新了我的答案。如果这确实是问题所在,“长期不同的讨论为什么”唐罗比:老实说,我相信java 7中仍然如此的主要原因是向后兼容。我相信如果设计师可以在不改变java向后兼容准则的情况下改变它,他们会……但我不是Oracle的架构师,所以我可能错了。我也相信这是离题的。这是indeed问题,原因在相关问题中。