views:

82

answers:

2

Hi guys,

I want to merge Two HashMaps.

I could use map1.putAll(map2); but I don't want to overwrite the key's as yes they will have conflicting keys.

So the keys in each map will be like this

word1     word1
word2     word2
word3     word3

and when I merge them I would like:

word1 word2 word3 word4 word5 word6

It can just overwrite the keys, aslong as the keys are incremental and use the first key text i.e. reads one of the pairs and extracts 'word' so each would be word1 word2.

But the other caveat I was thinking of the mobile environment and what I can do without having to put up a loading screen or even capable of.

So as a starter I suppose:

    HashMap<String, Object> hm1 = new HashMap<String, Object>();
    hm1.put("key1", "a");
    hm1.put("key2", "a");
    hm1.put("key3", "a");
    HashMap<String, Object> hm2 = new HashMap<String, Object>();
    hm2.put("key1", "1");
    hm2.put("key2", "2");
    hm2.put("key3", "3");

    HashMap<String, Object> newHM = new HashMap<String, Object>();      
    String keyWord = "";
    for (String  s: hm1.keySet()) {
        keyWord = s;
        break;
    }
    int count = 0;
    for (Object o : hm1.values()) {
        newHM.put(keyWord+count, o);
    }
    for (Object o : hm2.values()) {
        newHM.put(keyWord+count, o);
    }

But I'm wondering, how efficient is this? It looks correct, And is there a better way to do it? I don't want to use extra object's unnecessarily

A: 

If your keys are incremental an basically represent a simple index, you should use a List.

You could try your own implementation of List which will also store a keyword.

class KeyWordedArrayList<T> extends ArrayList<T>{
    private final String keyword;

    public KeyWordedArrayList(String keyword){
        this.keyword = keyword;
    }

    public String getKeyword(){
        return keyword;
    }
}

You can also do an implementation of Map :

class KeyWordedMap<T> extends HashMap<Integer, T> {
    private final String keyword;

    public KeyWordedMap(String keyword) {
        this.keyword = keyword;
    }

    public String getKeyword() {
        return keyword;
    }

    @Override
    public void putAll(Map<? extends Integer, ? extends T> m) {
        for (Map.Entry<? extends Integer, ? extends T> entry : m.entrySet()) {
            int i = entry.getKey();
            while (this.containsKey(i)) {
                i++;
            }
            this.put(i, entry.getValue());
        }
    }
}
Colin Hebert
That is a valid point, however at some instances when I instantiate this hashmap object the key's aren't incremental so I want the hashmap object to work in both situations. ( I wouldn't call the merge method in this situation).I could separate this out into two separate objects, but I don't think that should be my solution.
Blundell
@Blundell, updated with a Map implementation.
Colin Hebert
@Colin - cool I get that thanks - I assume you think this is the optimal answer then? it uses the least new objects etc. Answered the question again so anyone looking at my Q can see the Answer
Blundell
@Blundell, Yes I think it the best way to deal with this ;) But I maintain my idea to have a separated keyword.
Colin Hebert
A: 

To match my example it would be:

@Override
public void putAll(Map<? extends String, ? extends Object> m) {
    for (Map.Entry<? extends String, ? extends Object> entry : m.entrySet()) {
        String keyWord = "";
        for (String  s: this.keySet()) {
          keyWord = s.substring(0, s.length()-1);
          break;
        }
        int i = 0;
        while (this.containsKey(i)) {
            i++;
        }
        this.put(keyWord +i, entry.getValue());
    }
}
Blundell