简体   繁体   中英

Custom key for a HashMap

I need to map a [Integer, List<Integer>] key to an Integer . I have considered the following approaches and am struggling to figure which is most beneficial, given that speed is key.

WHY I NEED THIS?

There is a 2D array. Each row is the number of lines going out of a station. Each row contains the lines originating from a subway. So, subway stations are numbered 0,1,... All rows have the same number of elements (same number of lines originating from all stations). 0th index of a row gives the destination on taking the 0th line. 1th index of a row gives the destination on taking the 1th line,... The rth element of the list for station k, gives the station directly reachable by taking line r from station k. Now, suppose you are lost at one of the stations. Independent of which station you are at, if you take a certain combination of paths, you will arrive at a common station. This is called a meeting path. I need to find if, for a given subway configuration, there is a meeting path possible. Eg. For subway = [[2, 1], [2, 0], [3, 1], [1, 0]] , taking line1 then line0 from any station, results in ending up at station2. So [1,0] would be a meeting path. I have generated a set of paths, that would look like [[0],[1],[0,0],[0,1],[1,0],[1,1],[0,0,0],[0,0,1],...]. I have to traverse the path from each station to see if I end up at the same station for all the stations. Say, we consider station0, and am considering path[0,0,1]. I would already have traversed the path [0,0]. Instead of traversing that portion again, I can use whatever result I had after traversing [0,0] and take line1 from that point, to end up at my new destination. This is why I need to cache ([startStation, pathList], destination). Moreover, if this way of searching for a meeting path doesn't work for say, 8 degrees of paths, we need to check if closing down a certain station will result in a meeting path. This is more so, why I want to use a [startStation, pathList] as a key. Link to full problem statement is at the end of the post.

First approach: Create a new unmodifiableList with the value at the 0th index as the aforementioned Integer and the rest as the List<Integer> . I would use this unmodifiableList as the key.

Second approach: Create a new unmodifiableList with the value at the 0th index as the aforementioned Integer and the 1st index as the hashCode for an unmodifiable copy of List<Integer> . I would use this unmodifiableList as the key. [Thilo correctly noted in the comments that this approach would cause collisions].

Third approach: [Nested Map] Create a mapping from an Integer to another HashMap that maps from List<Integer> to Integer . [Similar to the accepted answer here ]

Fourth approach: Make an object with Integer and List<Integer> as fields, and override the equals and hashCode methods. This would serve as the key.

I feel the third approach is the simplest, and would make for the most readable code. I am struggling to weigh the pros and cons with respect to all 4 designs. Speed is key here.

This is with reference to a question on the Google Foobar challenge [ problem ]

I would favour using a custom class, you can make it more readable by using your IDE to generate getters, setter, equals , hashCode and toString() methods.

Note: using a HashMap instead of an object has a much higher overhead and make your program more difficult to profile later.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM