我已经声明了一个 LinkedList,其中 Frame 是我的列表项。
private LinkedList<Frame> linkedList = new LinkedList<Frame>();
我意识到,当我测试indexOf时,即使列表包含查询的项目,也会返回-1。文档指出“如果此列表不包含该元素,(...) 或 -1。”。
https://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html#indexOf(java.lang.Object)
看看这些奇怪的结果:
linkedList.size() -> 1
linkedList.get(0) -> frame
linkedList.contains(linkedList.get(0)) -> false
linkedList.indexOf(linkedList.get(0)) -> -1
我是不是忽略了什么?知道发生了什么吗?
我正在从各个线程访问该列表,但没有同步。这可能是导致问题的原因吗?
--
日志(见下文):
12-05 20:30:00.101 16446-16461/cc.closeup I/System.out﹕ **** TEST 0
12-05 20:30:00.301 16446-16476/cc.closeup I/System.out﹕ **** TEST -1
12-05 20:30:00.856 16446-16461/cc.closeup I/System.out﹕ **** TEST 0
12-05 20:30:01.051 16446-16476/cc.closeup I/System.out﹕ **** TEST -1
12-05 20:30:01.601 16446-16461/cc.closeup I/System.out﹕ **** TEST 0
12-05 20:30:01.801 16446-16476/cc.closeup I/System.out﹕ **** TEST -1
12-05 20:30:02.356 16446-16461/cc.closeup I/System.out﹕ **** TEST 0
12-05 20:30:02.551 16446-16476/cc.closeup I/System.out﹕ **** TEST -1
12-05 20:30:03.101 16446-16461/cc.closeup I/System.out﹕ **** TEST 0
12-05 20:30:03.301 16446-16476/cc.closeup I/System.out﹕ **** TEST -1
最佳答案
仔细查看 javadoc 中的 contains
和 indexOf
。它声明这些方法使用 equals
方法确定元素是否在集合中。
如果 contains
和 indexOf
表示“它不存在”,则列表中存在的对象与您正在测试的对象不同......根据对象的 equals(Object)
实现。
另一种可能性是您正在从不同的线程访问/更新集合,并且您没有正确同步。这可能会导致一个线程看到列表的陈旧版本或不一致版本。
Would you think I am fine if I synchronize the list itself?
Collections.synchronizedList(new LinkedList<>())
如果您通过同步列表执行所有操作并且不使用迭代器,则每个单独的操作都将是线程安全的和原子的。但是:
- “同步列表”的迭代器不同步,并且
- 如果您需要以原子方式同步/执行一系列操作,这没有帮助。
例如:
List<Integer> l = Collections.synchronizedList(new LinkedList<>());
// Make the list visible to other threads ...
for (int i = 0; i < l.size(); i++) {
Integer ii = l.get(i);
...
}
虽然 l.size()
始终给出当前大小,但大小可能在 l.size()
和 l.get(i)
调用之间发生变化,从而可能导致异常。
简而言之... Collections.synchronizedList(...)
并不是所有涉及列表的线程安全问题的解决方案。你仍然需要考虑你在做什么。
关于java - 如果对象包含在列表中,为什么 LinkedList.indexOf() 返回 -1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27328088/