kuncajs
kuncajs

Reputation: 1098

Hashcode from reflection?

I have got

interface Module {
    List<String> parse();
}

There are several implementations of the interface and in application I would like to have a HashSet<Module> which ensures there is only one instance of each module. For this I need a proper hashCode for each class. The proper implementation of hashCode would be the one that returns the same constant for various instances of one module class but different one for different modules.

To create a nice design solution I would like to compute the hashCode from name of the module like:

public int hashCode() {
    return ConcreteModule.class.getName().hashCode();
}

but this code would be the same for every implementation of interface... My idea was to create an abstract module which implements the hashcode but is it possible to reach the name of the class which extends this abstract class? Like:

public abstract class AbstractModule implements Module {
    public int hashCode() {
        // get the class name of class extending the abstract module
        // and return hashcode of its string name
    }
}

and then

public class ConcreteModule extends AbstractModule implements Module {
    // implementation of parse() no need to create hashcode for each module
}

Would you suggest to create hashCodes for each module or is it possible to create something I am trying? Any suggestions or advices are welcome. Thanks in advance

Upvotes: 0

Views: 936

Answers (3)

rolfl
rolfl

Reputation: 17707

After some thought, what you want to do is key the map off the class, not the instance....

HashMap<Class<? extends Module>, <Module>> mymap = .....

Then you have just one value for each class type. You can put with:

mymap.put(module.class(), module);

Upvotes: 2

JB Nizet
JB Nizet

Reputation: 691963

You could simply implement it like the following:

@Override
public final int hashCode() {
    return this.getClass().getName().hashCode();
}

@Override
public final boolean equals(Object other) {
    if (other == this) {
        return true;
    }
    if (other == null) {
        return false;
    }
    return other.getClass().equals(this.getClass());
}

But I'm not sure it's the best idea. Moreover, you can't guarantee that all implementations of the interface extend your abstract class.

You could simply maintain a Map<Class<? extends Module>, Module>. Each module implementation would add itself to your registry, and if the class of the module is already in the map, you would simply reject or ignore the new module instance.

Upvotes: 1

jtahlborn
jtahlborn

Reputation: 53694

how about:

return getClass().getName().hashCode();

Although, you could just as easily use:

return getClass().hashCode();

Upvotes: 1

Related Questions