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.
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 usesequals(). TheObject.equals()would work so it could be that you have overridden the defaultequalsmethod and there is a bug in it.This is also what ORMLite does. If the collection is eager then it calls
contains()on the innerArrayListfor the item which would useequals(). If the collection is lazy then it uses the iterator across the table and, again, usesequals()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
Episodeobject from the database. Then, when you callcontains(), it iterates again through the collection creating newEpisodeobjects from the database. It tries to compare the two objects but they will never be equal if you are usingObject.equals()because there are not the same object reference.You must to override the
equals()method to getcontains()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
Showobject, with an eager collection ofSeasonobjects, each with another eager collection ofEpisodeobjects. 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 themaxEagerLevel = 2(or more) on theShowobject’s collection. See the documentation onmaxEagerLevel.