2013-06-12 112 views
0

我有一个类'CoAutoria',它包含了一个'作者'类(现在只有一个名称)和这些作者共同拥有的文章数。
为了找出合作作者前10名(关于文章数量),我创建了一个'CoAutoria'的TreeSet,用于保存每对文章的总数。 我需要循环浏览多年的地图,收集不同的作者和他们各自的一组作者。然后,为每一对创建一个'CoAutoria'实例,并将其添加到树集(如果它不存在);或者简单地将它的文章数量与文章中现有的文章数量相加。包含给出错误的结果

我已经创建了compareTo方法,将它插入到treeset中,并创建了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的形式),但有时它不会......对于我读过的内容,等号的方法,所以这不适用于发生......对吧?

[编辑:] 由于第一篇文章,我开始想,也许这个问题上居住的compareTo..So我把它改成

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值..但缺少一些东西

+0

在您的示例中没有足够的内容,但是....不是使用contains,而是使用equals循环,您可能会发现使用equals()进行测试也不起作用。 –

+1

@DariusX。问题不在于他的平等,而在于“compareTo”函数。当compareTo函数无法正常工作时,对有序集合的'contains'方法也不会。 – greedybuddha

回答

2

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

实施例(假定author1author2不同):

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

此致将返回1两个以上的情况下,这将使得有序集合无法正常工作,没有元素是有史以来smaller。作为另一个例子,想象一下如果你有一个Binary Tree(一个有序的集合),它具有元素[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; 
} 
+0

感谢您的答复..我试图改进我的compareTo方法(我编辑了最初的帖子),但我仍然在犯一些错误.. –

+0

看看我的修改答案。你的方法仍然是错误的,所以试试我的建议。 – greedybuddha

+0

是的,刚才我想,如果我没有以相同的方式订购我的订单,我不能使用我创建的方法,谢谢! 在我的情况下,另一个解决方案是可行的,就是在创建'CoAutoria'实例时订购作者。但是在我无法做到这一点的情况下,你的方法会更有用:) –