Andrew Pearce
Andrew Pearce

Reputation: 67

Use the same object as both key and value in a HashMap

I've re-worded this search about as many times as I think I can and I've come up with nothing, so either this hasn't been asked before, or I don't know HOW to ask.

I am working on a personal project that boils down to trying to find the shortest path from a starting state to a finishing state.

There are too many (more than 2^64) states so I can't generate the entire graph. However, each state contains enough information to determine all the states adjacent to it. There are (infinitely) many paths from a state to another, and I am only interested in the shortest. This requires me to know if I've reached been to a state before, and also how I got there the first time.

My state object contains all the state information, as well as the depth of the path that lead me there, and the move I made to get there from the previous state in that path. If I get to the same state following a different path, the state information will be the same, but the depth and previous move fields will be different.

I want a data structure that will tell me if I have visited that state before, and if I have, retrieve the depth and previous state information from it.

The best solution I have come up with so far is to use a HashMap which maps a state to a state, and use the same state object as both the key and value, as in: myHashMap.put(myState, myState)

I've implemented hashCode() and equals() such that two states will be considered "equal" if their state information is the same (i.e. we've been in this room before) regardless of how I got there (i.e. which door I used to enter the room).

This seems rather silly but I can't think of another way (with fast storage/access) to store the information about whether I've been to a state and how I got there.

Does my plan make sense, or is there a better way?

Upvotes: 0

Views: 126

Answers (2)

Sleiman Jneidi
Sleiman Jneidi

Reputation: 23349

If you see yourself storing key and value as the same value, then it is a Set what you really need.

 Set<State> set = new HashSet<>();
 set.put(stat1);

And by the way your solution is not very far from that as HashSet is backed by a HashMap behind the scenes which means a HashSet has the performance characteristic as those of HashMap and relies on equals and hashCode methods.

Upvotes: 1

Michael
Michael

Reputation: 786

You say that "I want a data structure that will tell me if I have visited that state before, and if I have, retrieve the depth and previous state information from it."

A Set (HashSet is likely better than a TreeSet for what you've described) will do the first part. Now, I see that you are trying to use a Map in order to do the second half which is retrieving the information. However, if you are already able to check if you've visited a state, that means you have a reference to the state. So, you don't need a map at all.

/*  Marking a state as visited  */
Set<State> visited = new HashSet<>();
visited.put(currentState);

/*  Checking if visited/retrieving  */
if (visited.contains(currentState)) {
    // already visited
} else {
    // do something with 'currentState'
}

Upvotes: 1

Related Questions