Java ArrayList:contains()方法在arraylist包含给定对象时返回false

我有一个contains()方法的问题,即使ArrayList包含给定的Object ,它返回false。 我的代码如下:

 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

当涉及到这个时,数组的hashCode()equals()有点破碎(这是一个长期不同的讨论原因)。

可能的解决方法是使用ArrayList>而不是ArrayListArrayListequals()方法将如您所愿。

例如:

  ArrayList l1 = new ArrayList<>(); ArrayList l2 = new ArrayList<>(); l1.add("asdf"); l2.add("asdf"); ArrayList> coll = new ArrayList<>(); coll.add(l1); System.out.println(coll.contains(l2)); 

正如预期的那样,将产生true

如果它应该返回SAME数组而不是创建新数组,请查看getPendingTransaction和getSentTransactionRequests。 其次,尝试调试并查找数组对象id。 如果这不相同,但它应该是(并包含相同的元素),请尝试解决此问题(例如创建比较器或List或类似的东西)。

问题是数组的equals被定义为引用相等。 换句话说,根据equals方法,包含相同元素的两个不同数组不相等。

如果您希望“事务”对象的equals基于字符串的相等性,则需要创建一个自定义类来保存String[] ,并覆盖equals方法和hashcode方法。


顺便说一句,数组equals(Object)方法不是“有点破碎”。 定义的equals语义只是反映了任何数组对象本身都是可变的这一事实。

这是因为String [] transaction是对象。 当你调用contains list时,使用equals方法将新对象与其他对象进行比较。 想象一下就好

 new Object().equals(new Object()) 

如果你必须使用List ,可能你似乎没有运气使用equals()hashCode()似乎……

也许你最好创建比较对象的方法

就像是

 public static boolean stringArrayListEquals(List list, List 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; } 

要测试contains() ,你需要另一个循环......

虽然你应该认真使用List>