Skip to content
Advertisement

HashMap: Is there a way to search by hashcode and not by key?

I may sound completely wrong but: I’ve read as many posts as I could find here about HashMap and hashcode . I did not get what I was looking for exactly. I am going to try to be as precise as I can.
Let’s say I have a huge hashmap where :

  • keys are of type my_struct and values as well
    Now, my_struct is made of 2 Lists that can have big sizes (so one entry has a respectable size on its own).
    Keys and values have a special relation : values are for sure already keys in the dictionary (something like ancenstor – descendant relation).
    I was wondering whether instead of storing values of my_struct , I could store an int and then using this “int as a key” to search for the relative entry. In pseudocode I could describe it as such:
  HashMap<my_struct, int> h = new HashMap<>(); 
  ......
  my_struct descendant = value;
  int id = a(value);     // returns an id for this value
  h.put(ancenstor, id);
  ...
  // after some time I want to find the corresponding value of id 
  int key = h.getValue(ancestor);  // == id
  if(h.contains(b(key)){
     ...
   }

So basically I am looking for :
a method : a() that turns a mystruct –>int
a method : b() that turns an int —> my struct
Of course, both should be a 1-1 functions.
After reading Java8 documentation a() must be int hashCode() but what about b() is there something in Java?

Advertisement

Answer

HashMap: Is there a way to search by hashcode and not by key?

Literally … no.


OK, so I am assuming that this is a complete and accurate description of your real problem:

So basically I am looking for :

  • a method : a() that maps a my_struct –> int
  • a method : b() that maps an int –> my_struct

Of course, both should be a 1-1 functions.

Got that.

After reading Java8 documentation a() must be int hashCode()

That is incorrect. hashCode() is not 1-1. In general, multiple objects can have the same hashCode(). Note that even identity hashcodes (as returned by Object.hashCode) are not guaranteed unique.

You could implement a my_struct.hashCode method that returns a unique integer, but the only practical way to do this would be to allocate a unique number when you create each my_struct instance, and store it in a field of the object. And that has the problem that your my_struct.equals method has to return true if and only if the my_struct instances are the same instance.

But if you can live with those limitations, then a() can indeed be my_struct.hashCode.

If you generate the numbers for the my_struct objects sequentially starting at zero, you can add all of the my_struct instances to an ArrayList<my_struct> as you create them, then you can implement b() as theList.get(int).


In code (not thread-safe!!):

public class my_struct {
    private static int next = 0;
    private static List<my_struct> all = new ArrayList<>();
    private int ordinal;
    // other fields

    public my_struct(...) {
       // initialize fields
       this.ordinal = next++;
       all.add(this);
    }

    public boolean equals(Object other) {
        return other instanceof my_struct &&
             ((my_struct) other).ordinal = this.ordinal;
    }

    public int hashCode() {
        return ordinal;
    }

    public static my_struct(int ordinal) {
        return all.get(ordinal);
    }
} 

But you should also be able to see that you don’t have to use the ordinal as the hashcode and implement hashCode() and equals(Object) as above. It depends on what else you are doing with these structs.


Note that this is not the same as using an IdentityHashMap.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement