bstrong
bstrong

Reputation: 660

In Java how can I check if an object is in a linked list?

Below is my class. The insertSymbol method is supposed to add an object to the linked list which is then added to a hash table. But when I print the contents of the hash table it has double entries. I tried to correct this by using "if(temp.contains(value)){return;}" but it isn't working. I read that I need to use @override in a couple of places. Could anyone help me know how and where to use the overrides? Thank you!

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

}

Upvotes: 2

Views: 4651

Answers (2)

Erik Pragt
Erik Pragt

Reputation: 14617

You have multiple options here. You'll need at least to add an equals (and therefor also a hashcode) method to your class.

However, if you want your collection to only contain unique items, why not use a Set instead?

If you still want to use a List, you can use your current approach, it just that the characteristics of a Set are that all items in a Set are unique, so a Set might make sense here.

Adding an equals method can quite easily be done. Apache Equalsbuilder is a good approach in this.

Upvotes: 5

Lee Meador
Lee Meador

Reputation: 12985

You don't need the 2nd line when you add a new value with the same key:

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

Let me explain something that @ErikPragt alludes to regarding this code:

if(temp.contains(value)){

What do you suppose that means?

If you look in the javadocs for LinkedList you will find that if a value in the list is non-null, it uses the equals() method on the value object to see if the list element is the same.

What that means, in your case, is that your class SymbolTableItem needs an equals() method that will compare two of these objects to see if they are the same, whatever that means in your case.

Lets assume the instances will be considered the same if the names are the same. You will need a method like this in the 'SymbolTableItem` class:

@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());
}

It it depends on more fields, the equals will be correspondingly more complex.

NOTE: One more thing. If you add an equals method to a class, it is good programming practice to add a hashcode() method too. The rule is that if two instances are equal, they should have the same hashcode and if not equal they don't have to be different hashcodes but it would be very nice if they did.

If you use your existing code where only equals is used, you don't need a hashcode, stricly. But if you don't add a hashcode it could be a problem someday. Maybe today.

In the case where the name is all that matters, your hashcode could just return: this.getName().hashcode().

Again, if there are more things to compare to tell if they are equal, the hashcode method will be more complex.

Upvotes: 2

Related Questions