0

TreeMapを使用して同義語辞書を作成する必要があります。TreeMapは<Word, ArrayList<Word>>タイプです。つまり、Wordで表されるキーごとに、同義語のリストがあります。以下のメソッドを使用して辞書の内容を一覧表示したい場合、返されるArrayListがnullであることがわかります。私に何ができる?コードをトレースしようとしましたが、エラーが見つからないようです。方法は次のとおりです。

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は、挿入された要素の一部に対してnullです。私は時計をチェックしましたが、そこにはありません。私は何をすべきか ?

wordListはTreeMap<Word, ArrayList<Word>>;

EDIT-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);
  }

}

編集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;
}

}
4

4 に答える 4

2

compareToメソッドが間違っています。契約では、A> Bの場合、B <Aである必要があります。内容が等しくない場合、実装は常に1を返します。

次のように実装する必要があります。

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

(そして、WordクラスはComparable<Word>Comparableではなく実装する必要があります)。

TreeMapはこのメソッドを使用して、ある単語が別の単語よりも大きいか小さいかを判断し、このメソッドは一貫性のない結果を返すため、Mapも一貫性のない結果を返します。

于 2012-05-12T15:24:51.760 に答える
0

同義語を挿入すると、すべて問題がないことを確認しましたか?ところで、文字列を連結するにはStringBuilderを使用する必要があり(perfの方が優れています)、複数のgetとイテレータではなく、worklist.entrySet()を使用してキーと値を同時に反復することをお勧めします。

于 2012-05-12T15:06:04.790 に答える
0

文字列を連結する代わりに、for-eachループ、StringBuilderなどの適切なJavaイディオムを使用するように既存のコードをクリーンアップしましsize--た。そのようなハッキングは避けてください。

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;
        }
      }
    }
  }
}
于 2012-05-12T15:11:33.670 に答える
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およびその他の構造は、同じ単語を表すWordクラスの2つのインスタンスが実際に等しいことを識別できます。

于 2012-05-12T15:19:35.237 に答える