2

下面是我的课。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);
    }

}
4

2 回答 2

5

您在这里有多种选择。您至少需要在您的类中添加一个 equals(因此还有一个哈希码)方法。

但是,如果您希望您的收藏只包含独特的项目,为什么不使用Set呢?

如果您仍想使用 List,则可以使用当前的方法,只是 Set 的特征是 Set 中的所有项目都是唯一的,因此 Set 在这里可能有意义。

添加equals方法可以很容易地完成。Apache Equalsbuilder是一个很好的方法。

于 2013-07-08T18:51:34.957 回答
2

当您使用相同的键添加新值时,您不需要第二行:

temp.addLast(value);
SymbolTable.put(key, temp); // <-- Not needed. Its already in there.

让我解释一下@ErikPragt 提到的关于这段代码的一些事情:

if(temp.contains(value)){

你认为这意味着什么?

如果您查看javadocs,LinkedList您会发现如果列表中的值非空,它会使用对象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 将相应地更复杂。

注意:还有一件事。如果向类添加 equals 方法,那么添加hashcode()方法也是一种很好的编程习惯。规则是,如果两个实例相等,它们应该具有相同的哈希码,如果不相等,它们不必是不同的哈希码,但如果它们这样做会非常好。

如果您在仅使用的地方使用现有代码,equals则严格来说不需要哈希码。但是,如果您不添加 a hashcode,总有一天它可能会成为问题。可能是今天。

在名称很重要的情况下,您的哈希码可以只返回:this.getName().hashcode()

同样,如果要比较更多的东西来判断它们是否相等,那么 hashcode 方法会更复杂。

于 2013-07-08T18:57:25.110 回答