对于直接从集合中提取的对象,为什么".contains"会返回false?

Eru*_*uza 4 java collections ormlite

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));
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么以上代码打印错误?

我正在使用一个集合,因为这是ormlite允许的.我认为这个问题可能是由ormlite引起的,因为一个非常相似的类有一个相同的方法来打印true.

我要做的是修改返回的对象:

public Episode findEpisode(int num) {
    checkEpisodes("Find: ");
    for(Episode episode : this.episodes) {
        if(episode.getNumber()==num) {
            return episode;
        }
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

但是不保存对该对象的修改.我假设因为它不包含在Collection中.

我的解决方案,但有效但不理想:

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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您需要查看更多我的代码,请问,项目有点涉及,但它托管在sourceforge上,如果有必要,我可以发布一个链接.

Gra*_*ray 10

for(Episode episode : this.episodes) {
    System.out.println(string + this.episodes.contains(episode));
}
Run Code Online (Sandbox Code Playgroud)

为什么以上代码打印错误?

在一般意义上,使用标准集合,我可以看到你的equals()方法中是否存在错误的唯一方法.对于大多数集合,contains()迭代集合和使用equals().它Object.equals()会工作,所以你可能已经覆盖了默认equals方法,并且它有一个错误.

这也是ORMLite的作用.如果集合急切,那么它会调用contains()内部ArrayList的项目来使用equals().如果集合是惰性的,那么它在表中使用迭代器,并再次equals()用于查看是否匹配.

编辑:

啊哈.您声明您没有覆盖该equals()方法.

要记住的一个重要事项(就ORMLite而言)是这是一个惰性集合,内存中没有对象的存储.当您在延迟集合中进行迭代时,您Episode将从数据库中获取对象的实例.然后,当您调用时contains(),它会再次遍历集合,Episode从数据库中创建新对象.它试图比较两个对象,但如果你使用它们将永远不会相等,Object.equals()因为没有相同的对象引用.

必须覆盖该equals()方法contains()才能使用于延迟集合.

此外,尽管您的帖子可能是代码的简化,但您可以考虑将延迟集合拉入数组,然后迭代它.你不能contains()在数组上做一个但是如果你需要搜索数组,你就不会在数据库中迭代两次.

编辑:

所以解决方案变得更加复杂.事实证明,OP有一个Show 对象,一个急切的Season对象集合,每个对象都有另一个热切的Episode对象集合.默认情况下,每当ORMLite具有嵌套的eager集合时,由于性能原因,内部集合将变为惰性集合.遗憾的是,4.40版本没有详细记录.您可以通过maxEagerLevel = 2Show对象的集合上设置(或更多)来更改此设置.请参阅文档maxEagerLevel.

@ForeignCollectionField(eager = false, maxEagerLevel = 2)
ForeignCollection<Season> seasons;
Run Code Online (Sandbox Code Playgroud)