2012-05-12 39 views
0

我必須使用TreeMap執行同義詞字典。 TreeMap的類型爲<Word, ArrayList<Word>>。這意味着對於由Word代表的每個關鍵字,將會有一個同義詞列表。當我想列出字典的內容時,通過使用下面的方法,我發現返回的ArrayList爲null。我能做什麼?我試圖追蹤代碼,但我似乎沒有發現錯誤。 方法是:由TreeMap返回的空ArrayList Java

public String listContent() { 
    Set set = wordList.keySet(); 
    Iterator it = set.iterator(); 
    String result = new String(); 
    ArrayList<Word> words = new ArrayList<Word>(); 
    while (it.hasNext()) { 
     Word temp = (Word) it.next(); 
     words = wordList.get(temp); 
     if (words != null) { 
      Iterator it2 = words.iterator(); 
      result += temp.getContent(); 
      result += " - "; 
      int size = words.size(); 
      while (it2.hasNext()) { 
       result += ((Word) it2.next()).getContent(); 
       if (size != 1) 
        result += ", "; 
       size--; 
      } 
      result += "\n"; 
     } 
    } 
    return result; 
} 

由wordList.get(TEMP)返回的ArrayList中爲空一段插入的元件。我檢查了手表,但在那裏,他們沒有。我該怎麼辦 ?

單詞表是一個TreeMap<Word, ArrayList<Word>>;

編輯 - 在addWord方法

public void addWord(String content1, String content2) 
{ 
    Word w1 = new Word(content1); 
    Word w2 = new Word(content2); 
    Set set = wordList.entrySet(); 
    Iterator it = set.iterator(); 
    boolean ok=false; 
    while(it.hasNext()) 
    { 
    Map.Entry<Word,ArrayList<Word>> temp = (Map.Entry<Word,ArrayList<Word>>) it.next(); 
    if(temp.getKey().getContent().matches(content1)) 
    { 
     ArrayList<Word> words = temp.getValue(); 
     Iterator it2 = words.iterator(); 
     if(words.isEmpty()) words.add(w2); 
     else 
     { 
     boolean ok2=true; 
     while(it2.hasNext()) 
     { 
      Word tempy = (Word) it2.next(); 
      if(tempy.getContent().equals(content2)) 
      { 
      ok2=false; 
      break; 
      } 
     } 
     if(ok2) words.add(w2); 
     } 
     ok=true; 
    } 
    } 
    if(!ok) { 
    ArrayList<Word> tempys = new ArrayList<Word>(); 
    tempys.add(w2); 
    wordList.put(w1,tempys); 
    } 

} 

EDIT 2 - 詞類

public class Word implements Serializable,Comparable { 

private String content; 

public Word (String content) 
{ 
    this.content = content; 
} 

public void setContent(String content) 
{ 
    this.content=content; 
} 

public String getContent() 
{ 
    return content; 
} 

@Override 
public int compareTo(Object o) { 
    if(((Word)o).getContent().equals(this.getContent())) return 0; 
    return 1; 
} 

} 
+0

想要編輯,但你更快 –

+2

你可以顯示代碼你在哪裏填充'TreeMap'? – Tudor

+1

同時向我們展示Word類的代碼。無論如何,爲什麼你需要這個類,爲什麼不使用String?會有更少的事情可能出錯。 – ZeroOne

回答

2

您的compareTo方法是錯誤的。合同是,如果A> B,那麼你必須有B < A.如果內容不相等,你的實現總是返回1。

你應該實現這樣的:

@Override 
public int compareTo(Word w) { 
    return this.content.compareTo(w.content); 
} 

(和Word類應該實現Comparable<Word>並不具備可比性)。

由於TreeMap使用此方法來判斷某個單詞是否大於或小於另一個單詞,並且由於此方法返回不一致的結果,所以Map也返回不一致的結果。

+0

這是問題 - 我沒有足夠的重視正確覆蓋compareTo方法。謝謝! –

0

你檢查,當你插入一個同義詞一切好嗎? 順便說一句,你應該使用StringBuilder來連接字符串(在perf中更好),你最好使用worklist.entrySet()來同時迭代key和value,而不是幾個get和iterator。

+0

是的,我檢查了手表,一切都在那裏 –

0

我已經清理了你現有的代碼,以便使用適當的Java語言,比如for-each循環,StringBuilder而不是連接字符串,避免那種黑客,類似的東西。

public String listContent() { 
    final StringBuilder result = new StringBuilder(); 
    for (Map.Entry<Word, List<Word>> e : wordList.entrySet()) { 
    final List<Word> words = e.getValue(); 
    if (words != null) { 
     result.append(e.getKey().getContent()).append(" - "); 
     final Iterator<Word> it = words.iterator(); 
     result.append(it.next().getContent()); 
     while(it.hasNext()) result.append(", ").append(it.next().getContent()); 
     result.append("\n"); 
    } 
    } 
    return result.toString(); 
} 

這裏也是addWord的清理版本,但仍然是程序邏輯的沉重混亂。如果有人對此有耐心,我鼓勵他偷竊並改善這一點。

public void addWord(String content1, String content2) { 
    final Word w1 = new Word(content1), w2 = new Word(content2); 
    final Set<Map.Entry<Word, List<Word>>> set = wordList.entrySet(); 
    for (Map.Entry<Word, List<Word>> temp : set) { 
    if (!temp.getKey().getContent().matches(content1)) { 
     final List<Word> newList = new ArrayList<Word>(); 
     newList.add(w2); 
     wordList.put(w1,newList); 
     break; 
    } 
    final List<Word> words = temp.getValue(); 
    if (words.isEmpty()) words.add(w2); 
    else { 
     for (Word w : words) { 
     if (w.getContent().equals(content2)) { 
      words.add(w2); 
      break; 
     } 
     } 
    } 
    } 
} 
0

的addWord方法是烏七八糟,我得到一個頭痛的時候我嘗試看看,但我的猜測是,該系統無法正常工作,因爲Word類實現既不是equals方法也不方法hashCode。嘗試添加這些吧:

@Override 
public int hashCode() { 
    return this.content.hashCode(); 
} 

@Override 
public boolean equals(Object o) { 
    return this.content.equals(o); 
} 

有了這些方法TreeMap和其他結構都能夠識別代表同一個詞的詞類的兩個實例,的確都是平等的。

+0

他使用的是TreeMap。 compareTo方法在這裏很重要。 –

+0

@JBNizet即使這樣,他的'compareTo'方法的實現只能返回1或0,而不是-1。首先使用TreeMap的目的失敗了,不是嗎?我想這不是他的問題的原因(儘管我不會很驚訝,如果是),但無論如何。 – ZeroOne

+0

同意。這就是我在答案中所說的。這個問題肯定來自compareTo的這種不連貫的實現。 –