Reputation: 4977
I have declared a LinkedList, where Frame is my list item.
private LinkedList<Frame> linkedList = new LinkedList<Frame>();
I realized that when I test for indexOf -1 is returned even though the list contains the queried item. Documentation states "(...) or -1 if this list does not contain the element.".
https://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html#indexOf(java.lang.Object)
Look at these strange results:
linkedList.size() -> 1
linkedList.get(0) -> frame
linkedList.contains(linkedList.get(0)) -> false
linkedList.indexOf(linkedList.get(0)) -> -1
Did I overlook anything? Any ideas what's going on?
I am accessing the list from various threads without synchronization. Could this have caused the problem?
--
Log (see below):
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
Upvotes: 1
Views: 110
Reputation: 718886
Look carefully at the javadocs for contains
and indexOf
. It states that the methods determine if an element is in the collection by using the equals
method.
If contains
and indexOf
are saying "it isn't there" then the object that is present in the list is a different one to the one you are testing for ... according to the object's implementation of equals(Object)
.
The other possibility is that you are accessing / updating the collection from different threads, and you haven't synchronized properly. This can lead to one thread seeing a stale or inconsistent version of the list.
Would you think I am fine if I synchronize the list itself?
Collections.synchronizedList(new LinkedList<>())
If you perform all operations via the synchronized list AND you don't use the iterator, then each individual operation will be thread-safe and atomic. However:
For example:
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);
...
}
While l.size()
will always give the current size, the size might change between the l.size()
and l.get(i)
calls, potentially resulting in an exception.
In short ... Collections.synchronizedList(...)
is NOT a solution for all thread-safety problems involving lists. You STILL need to think about what you are doing.
Upvotes: 1