0

In my current project, I have implemented following data structure in Java.

Map<List<String>, Set<Subscriber>> regionSubscriber 
= new Hashtable<List<String>, Set<Subscriber>>();

I want to implement following operations on above mentioned data structure.

1) Check the key exists in this map or not ( similar to containsKey(Key) ). 2) Get the Set with key List ( similar to get(key) ).

I have tried with default functions of Map like containskey(Key) and get(Key) . But, they are not working because, here the Key is List (not a single Object).

Could you advise me on the implementation of the operations ? Let me know If you need more detail for clarity.


Update: I have written following equals() and hashCode() functions. Kindly check these functions. They are not working. Any corrections on these functions.

public boolean equals(Object obj){
        boolean booleanFlag = false;
        List<String> regionID = (List<String>) obj;
        for(int i=0; i< regionID.size() ; i++) {
            if ( regionID.get(i).equals(this.regionIDs.get(i)) ){
                booleanFlag = true;             
            } else {
                booleanFlag = false;
            }           
        }       
        return booleanFlag;     
    }



@Override
    public int hashCode() {
        int hashValue = 0;
        for(int i=0; i< regionIDs.size(); i++) {
            hashValue = hashValue + regionIDs.get(i).hashCode();
        }               
            return hashValue;
    }
Pankesh
  • 1,129
  • 2
  • 16
  • 46
  • do you need your key to be a list? – John Kane Jun 29 '12 at 11:35
  • 3
    I don't see why it wouldn't work with a list as long as that list has a proper implementation of equals/hashcode. A list is a single object, like any other. – Marko Topolnik Jun 29 '12 at 11:38
  • regarding "they are not working here because the key is `List` (not a single `Object`" - a `List` **is** a single `Object`. As @Marko says there is no reason why this shouldn't work. – Andrzej Doyle Jun 29 '12 at 11:41
  • I asked in terms of usability. I was assuming that the list of strings were basically a list of keys to a given set of subscriber. lookup on a single string is much easier if it is set up differently – John Kane Jun 29 '12 at 11:49
  • It will help if you post sample code illustrating the problem you're having using the normal Map methods. – Don Roby Jun 29 '12 at 11:50

2 Answers2

2

A List will work as a key, but you ahve to aware that you need to provide an exact match. i.e. you need to provide elements of the List which are equals(), have the same hashCode() and are in the same order.

Note: You cannot change a key once it has been used as a key. e.g. you can't add a List as a key and then changed it and expect the Map to still work.

Peter Lawrey
  • 498,481
  • 72
  • 700
  • 1,075
  • @Pater Lawrey : Many Many thanks for your pointer. could you help me to write equals() and hashCode() method, which has List as key. – Pankesh Jun 29 '12 at 11:51
  • 2
    +1 - this is what one should expect with key equality. A list ["A", "B"] is not the same as a list ["B", "A"]. And if you *want* them to be the same, then you don't care about ordering and so the key is actually a `Set` (or maybe a `Bag` if duplicates are allowed). A `Map` with a `List` key that wasn't order-sensitive on matching would be **broken**. – Andrzej Doyle Jun 29 '12 at 12:15
  • If you use a standard List like ArrayList or LinkedList you don't need to write your own. – Peter Lawrey Jun 29 '12 at 12:20
1

For the containsKey and get functions to work fine on a Map the class of the object used as a key need to implement the hashCode and equals methods.

What You need to do is to subclass the List type which You use as the key e.g.:

public class MyList extends ArrayList() {
    //constructors


    public boolean equals(Object obj) {
        // a good equals implementation
    }

    public int hashCode() {
        // a good hashcode implementation
    }
}

For information about how to implements the equals and hashCode methods to work us the should You can find some info under the following link: What issues should be considered when overriding equals and hashCode in Java?

Community
  • 1
  • 1
  • `java.util` collections already have perfectly appropriate equals and hashcode implementations. – Marko Topolnik Jun 29 '12 at 11:41
  • 1
    ArrayList already defines equals() and hashCode(). Are these not good enough? – Peter Lawrey Jun 29 '12 at 11:41
  • The default list equals and hashcode in my opinion don't work for a typical usecase as they are order dependent. Thats might be what You want but usualy isn't. But You are both right. I should have mentioned it in the response. – Tomasz Jędzierowski Jun 29 '12 at 11:47
  • @ Venc : Many thanks for your time and efforts. could you help me to write equals() and hashCode() method, which has List as key. – Pankesh Jun 29 '12 at 11:51
  • @Pankesh are you providing your own overridden implementation of `List`? The implementations in the standard library provide perfectly good `equlas()` and `hashCode()` implementations. – Andrzej Doyle Jun 29 '12 at 12:12
  • I could Pankesh but actually Andrzej Doyle made a very good point in the comment to the other answer. If You don't care about the order of elements You should use Set as the key. – Tomasz Jędzierowski Jun 29 '12 at 12:36