2013-06-12 135 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'實例時訂購作者。但是在我無法做到這一點的情況下,你的方法會更有用:) –