以下是我的课程。 insertSymbol方法应该将一个对象添加到链表中,然后将其添加到哈希表中。但是当我打印哈希表的内容时,它有两个条目。我试图通过使用“if(temp.contains(value)){return;}”来纠正这个问题,但它无效。我读到我需要在几个地方使用@override。谁能帮助我知道如何以及在哪里使用覆盖?谢谢!
import java.util.*;
public class Semantic {
String currentScope;
Stack theStack = new Stack();
HashMap<String, LinkedList> SymbolTable= new HashMap<String, LinkedList>();
public void insertSymbol(String key, SymbolTableItem value){
LinkedList<SymbolTableItem> temp = new LinkedList<SymbolTableItem>();
if(SymbolTable.get(key) == null){
temp.addLast(value);
SymbolTable.put(key, temp);
}else{
temp = SymbolTable.get(key);
if(temp.contains(value)){
return;
}else{
temp.addLast(value);
SymbolTable.put(key, temp);
}
}
}
public String printValues(){
return SymbolTable.toString();
}
public boolean isBoolean(){
return true;
}
public boolean isTypeMatching(){
return true;
}
public void stackPush(String theString){
theStack.add(theString);
}
}
答案 0 :(得分:6)
这里有多个选项。你至少需要为你的类添加一个equals(以及一个hashcode)方法。
但是,如果您希望您的收藏集仅包含唯一商品,为什么不使用Set呢?
如果您仍想使用List,您可以使用当前的方法,只是Set的特性是Set中的所有项都是唯一的,因此Set可能在这里有意义。
添加equals方法非常容易。 Apache Equalsbuilder是一个很好的方法。
答案 1 :(得分:2)
使用相同的键添加新值时,不需要第二行:
temp.addLast(value);
SymbolTable.put(key, temp); // <-- Not needed. Its already in there.
让我解释一下@ErikPragt提到的有关此代码的内容:
if(temp.contains(value)){
你认为这意味着什么?
如果查看LinkedList
的javadoc,您会发现如果列表中的值为非null,它会使用equals()
对象上的value
方法查看是否列表元素是相同的。
在您的情况下,这意味着您的班级SymbolTableItem
需要一个equals()
方法来比较其中两个对象,看看它们是否相同,无论您的情况如何。
让我们假设如果名称相同,则实例将被视为相同。你需要在'SymbolTableItem`类中使用这样的方法:
@Overrides
public boolean equals(Object that) {
if (that == null) {
return false;
}
if (this.getName() == null) {
return that.getName() == null;
}
return this.getName().equals(that.getName());
}
它取决于更多领域,等于相应地更复杂。
注意:还有一件事。如果向类添加equals方法,那么添加hashcode()
方法也是一种很好的编程习惯。规则是如果两个实例相等,它们应该具有相同的哈希码,如果不相等则它们不必是不同的哈希码,但是如果它们那么它将是非常好的。
如果您使用仅使用equals
的现有代码,则不需要严格的哈希码。但如果你不添加hashcode
,那么有一天它可能会成为一个问题。也许今天。
如果名称非常重要,您的哈希码就可以返回:this.getName().hashcode()
。
同样,如果有更多的事情需要比较来判断它们是否相等,那么哈希码方法会更复杂。