我必须使用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>>;
编辑 - 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;
}
}
答案 0 :(得分:2)
您的compareTo方法错误。合同是,如果A> B,那么你必须有B&lt;答:如果内容不相等,您的实现总是返回1.
你应该像这样实现它:
@Override
public int compareTo(Word w) {
return this.content.compareTo(w.content);
}
(Word类应该实现Comparable<Word>
,而不是Comparable)。
由于TreeMap使用此方法来判断某个单词是否大于或小于另一个单词,并且由于该方法返回非相干结果,因此Map也会返回不一致的结果。
答案 1 :(得分:0)
您是否在插入同义词时检查一切正常? 顺便说一句,你应该使用StringBuilder来连接字符串(更好的是perf),你最好使用worklist.entrySet()来同时迭代键和值,而不是几个get和迭代器。
答案 2 :(得分:0)
我已经清理了你现有的代码,使用正确的Java习语,比如for-each循环,StringBuilder而不是连接一个String,避免那个size--
hack,这样的东西。
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;
}
}
}
}
}
答案 3 :(得分: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类实例确实相等。