Why would ".contains" return false for objects pulled directly from a collection?
collections, java, ormlite
Solution
for(Episode episode : this.episodes) {
System.out.println(string + this.episodes.contains(episode));
}
Why would the above code print false?
In a generic sense, using a standard collection, the only way that I can see if if there are bugs in your `equals()` method. With most collections, `contains()` iterates through the collection and uses `equals()`. The `Object.equals()` would work so it could be that you have overridden the default `equals` method and there is a bug in it.
This is also what ORMLite does. If the collection is eager then it calls `contains()` on the inner `ArrayList` for the item which would use `equals()`. If the collection is lazy then it uses the iterator across the table and, again, uses `equals()` to see if matches.
Edit:
Aha. You state that you have not overridden the `equals()` method.
One important thing to remember (in terms of ORMLite) is that this is a lazy collection, there is no storage of the objects in memory. When you are iterating across the lazy collection, you get an instance of your `Episode` object from the database. Then, when you call `contains()`, it iterates again through the collection creating new `Episode` objects from the database. It tries to compare the two objects but they will never be equal if you are using `Object.equals()` because there are not the same object reference.
You must to override the `equals()` method to get `contains()` to work for lazy collections.
Also, although your post is probably a simplification of your code, you might consider pulling the lazy collection into an array and then iterating across that. You can't do a `contains()` on the array but if you needed to search the array, you wouldn't be iterating twice through the database.
Edit:
So the solution turned out to be more complicated. Turns out that the OP had a `Show` object, with an eager collection of `Season` objects, each with another eager collection of `Episode` objects. By default, whenever ORMLite has nested eager collections the inner one is turned into a lazy collection for performance reasons. This is not well documented in version 4.40 unfortunately. You can change this by setting the `maxEagerLevel = 2` (or more) on the `Show` object's collection. See the documentation on `maxEagerLevel`.
@ForeignCollectionField(eager = false, maxEagerLevel = 2)
ForeignCollection<Season> seasons;
Problem
``` private Collection<Episode> episodes = new ArrayList<Episode>(); public void checkEpisodes(String string) { for(Episode episode : this.episodes){ System.out.println(string + this.episodes.contains(episode)); } } ``` Why would the above code print false? I'm using a collection because that's what ormlite allows. I think the issue may be caused by ormlite anyways, because a very similar class has an identical method that prints true. What I'm trying to do is modify an object returned by: ``` public Episode findEpisode(int num) { checkEpisodes("Find: "); for(Episode episode : this.episodes) { if(episode.getNumber()==num) { return episode; } } return null; } ``` But modification of that object isn't saved. I'm assuming because it's not contained within the Collection. My solution, which works but isn't ideal: ``` public void modifyEpisode(Episode episode) { checkEpisodes("Modify: "); for (Iterator<?> it = this.episodes.iterator(); it.hasNext();) { if (((Episode) it.next()).getNumber()==episode.getNumber()) { it.remove(); addEpisode(episode.getNumber(), episode.getLink(), episode.getLinkLabel()); } } } ``` If you need to see more of my code, just ask, the project is somewhat involved, but it's hosted on sourceforge and I can post a link to it if necessary.