0

我有一个“CoAutoria”类,它应该包含一个“作者”类的 2 个实例(目前只有一个名称)以及这些作者共有的文章数量。
为了找出前 10 位共同作者(关于文章数量),我创建了一个“CoAutoria”树集,用于保存每对的文章总数。我需要循环浏览一张地图,收集不同的作者和他们各自的共同作者集。然后,对于每一对,创建一个 'CoAutoria' 的实例并: 将其添加到树集中(如果它尚不存在);或者简单地将其文章数与集合中现有的文章数相加。

我已经创建了 compareTo 方法,将其插入到树集中,并创建了 equals 方法,这样作者的顺序就无关紧要了。

这是主要代码:`

public class CoAutoria implements Comparable<CoAutoria>
{    
private Autor autor1;
private Autor autor2;
private int artigosComum;
(...) 
}


@Override
public int compareTo(CoAutoria a2)
{
    String thisAutor1 = autor1.getNome();
    String thisAutor2 = autor2.getNome();
    String caAutor1 = a2.getAutor1().getNome();
    String caAutor2 = a2.getAutor2().getNome();
    if((autor1.equals(a2.getAutor1()) && autor2.equals(a2.getAutor2())) || (autor1.equals(a2.getAutor2()) && autor2.equals(a2.getAutor1())))
    {
        return 0;
    }
    else
    {               

       return 1;
    }        
}    
@Override
public boolean equals(Object o)
{
    if(this == o)
    {
        return true;
    }


    if( o == null || o.getClass() != this.getClass())
        return false;

    CoAutoria ca  = (CoAutoria) o;
    String thisAutor1 = autor1.getNome();
    String thisAutor2 = autor2.getNome();
    String caAutor1 = ca.getAutor1().getNome();
    String caAutor2 = ca.getAutor2().getNome();
    if((thisAutor1.equals(caAutor1) && thisAutor2.equals(caAutor2)) || (thisAutor1.equals(caAutor2) && thisAutor2.equals(caAutor1)))
    {
        return true;
    }
    else
    {               
        return false;
    }

}

主要问题是:当我检查集合是否已经有某个“CoAutoria”实例时(我正在使用 TreeSet 的 contains() 方法),它给了我错误的结果......有时它会正确检查 Pair AB 已经存在于该集合中(以 BA 的形式存在),但有时它不存在......对于我所读到的内容,包含使用 equals 方法,所以这不应该发生......对吗?

[编辑:]从第一篇文章开始,我开始认为问题可能出在 compareTo 上。所以我将其更改为

public int compareTo(CoAutoria a2)
{
String thisAutor1 = autor1.getNome();
String thisAutor2 = autor2.getNome();
String caAutor1 = a2.getAutor1().getNome();
String caAutor2 = a2.getAutor2().getNome();
if(this.equals(a2))
{
    System.out.println("return 0");
    return 0;
}
else
{               
   int aux = thisAutor1.compareTo(caAutor1);
   if(aux != 0)
   {
       return aux;

   }
   else
   {
       return thisAutor2.compareTo(caAutor2);

   }

}        

}

但它仍然给我带来不好的结果..我想我现在想通了:如果它是相同的“CoAutoria”,我返回 0,如果不是,我会检查名称,并按它们的 compareTo 值排序..但是缺少一些东西

4

1 回答 1

2

您的contains方法正在中断,因为您的compareTo方法始终返回 0 或正数,没有负数。这意味着你compareTo的不一致。如果作者相同,正确的实现应该返回 0,或者当作者不同时返回正值负值。

示例(假设author1与 不同author2):

 int i = author1.compareTo(author2); // i should be positive or negative
 int j = author2.compareTo(author1); // j should be the opposite of i

对于上述两种情况,您的都将返回1,这将使有序集合无法正常工作,因为 no element is ever smaller。作为另一个例子,想象一下如果你有一个包含元素 [1-10] 的二叉树(一个有序集合)。如果您正在搜索元素 5,当将 5 与任何元素进行比较时,您的二叉树总是会说它相等或更大。

你应该如何改变它取决于你。但是一个想法是按名称对作者进行排序,然后遍历两个集合并按字典顺序比较作者。

编辑:即使您对方法进行了编辑,它们仍然不一致。尝试以下方法,它们不是最有效的,但除非您真的想优化速度,否则它们应该可以工作。请注意,它们首先排序以确保 author1 和 author2 在与另一个CoAutor也已排序的比较之前是有序的。我不做任何空值检查,并假设两者都是有效的作者。

@Override
public boolean equals(Object o){
    if (o == null || !(o instanceof CoAutoria)) return false;
    if (o == this) return true;
    return this.compareTo((CoAutoria)o) == 0;
}

@Override
public int compareTo(CoAutoria o) {
    List<String> authors1 = Arrays.asList(autor1.getNome(), autor2.getNome());
    List<String> authors2 = Arrays.asList(o.autor1.getNome(), o.autor2.getNome());
    Collections.sort(authors1);
    Collections.sort(authors2);
    for (int i=0;i<authors1.size();i++){
        int compare = authors1.get(i).compareTo(authors2.get(i));
        if (compare != 0)
            return compare;
    }
    return 0;
}
于 2013-06-12T18:19:42.170 回答