4

Is there a native data structure in java that accepts key value pairs and allows duplicates? I am creating a checklist of characters in a string but some characters occur more than once.

ex

j -> false
a -> false
v -> false
a -> false
Liondancer
  • 15,721
  • 51
  • 149
  • 255
  • Not sure about key/value pairs, but have you looked at `Bag`s? They allow duplicates, and there might be some thing usable there. – Trenin Feb 05 '14 at 19:35
  • Lots of answers suggest multimap from Guava but I wanted to use standard Java libraries – Liondancer Feb 05 '14 at 19:44
  • 1
    `List` + `Pair`, that's what i say ;) – bobbel Feb 05 '14 at 19:45
  • 1
    If you want standard Java, you will have to do a bit of extra work in simulating the "multimap' behavior, as suggested in the answers to your question. – PNS Feb 05 '14 at 19:49
  • [This answer in the possible duplicate](http://stackoverflow.com/a/6352551/1711796) suggests standard Java classes. – Bernhard Barker Feb 05 '14 at 20:21
  • Here's another possible duplicate - [HashMap with multiple values under the same key](http://stackoverflow.com/q/4956844) – Bernhard Barker Feb 05 '14 at 20:23

5 Answers5

5

You can simulate multiple key-value (KV) pairs by saving a list of values for each in a map. This is a standard implementation approach for "multivalue" maps.

So, if the key is a Character object and the value is Boolean, you can do

Map<Character, List<Boolean>> multimap = new HashMap<Character, List<Boolean>>();

and every time you want to add a new value to an existing KV pair in the map just call

multimap.get(key).add(value);

where key is the Character and value its corresponding Boolean value.

The Guava library by Google (free download) has a Multimap interface implemented in various ways, so essentially you can instantiate a MultiMap<Character, Boolean> map and use it accordingly. Similarly, you can get the Apache Commons Collections library and use its MultiValueMap class. You may also want to check the answers to a similar StackOverflow question, or another one.

If you only want to store one of each value per key, then a Set should be used in the place of the List.

PNS
  • 19,295
  • 32
  • 96
  • 143
  • If I am understanding this correctly you suggesting something that looks like this. `J, [F] | A [F,F] | V [F]` – Liondancer Feb 05 '14 at 19:48
  • Yes and that is how it would probably be implemented anyway. – PNS Feb 05 '14 at 19:49
  • I feel that your solution has better performance then Bobbel's when it comes to lookups but his seems like it would be easier to code – Liondancer Feb 05 '14 at 19:51
  • The approach I suggested is standard practice and you can easily create your own MultiMap class based on it, depending on which functions of the Map interface you want to use. It maintains the KV "map" behavior and does not replicate the key. – PNS Feb 05 '14 at 19:53
4

Use a List of Pairs:

public class Pair<T, U> {
    public final T key;
    public final U value;

    public Pair(T key, U value) {
        this.key = key;
        this.value = value;
    }
}

public class YourApp {
    public static void main(String[] args) {
        List<Pair<Character, Boolean>> charList = new ArrayList<Pair<Character, Boolean>>();
        charList.add(new Pair('j', false));
        charList.add(new Pair('a', false));
        charList.add(new Pair('v', false));
        charList.add(new Pair('a', false));

        for (Pair<Character, Boolean> pair : charList) {
            System.out.println(pair.key + " -> " + pair.value);
        }
    }
}

With the selfwritten generic Pair class you can hold a key and a value of any type you want. If you're adding pairs to a List, you can even hold duplicates of pair entries.

bobbel
  • 3,327
  • 2
  • 26
  • 43
3

You can use MultiMap<Character,Boolean> bcoz it allows duplicate key which exist in org.apache.commons.collections package.

or

You can use ArrayList and add the objects of the Class that contain attribute as char & boolean pair.

Kick
  • 4,823
  • 3
  • 22
  • 29
2

I do not know of a build in solution.

A quick alternative would be to use a simple ArrayList, and create an object that is a char/boolean pair that you can add to it.

useSticks
  • 883
  • 7
  • 15
1

commons.apache.org have MultiHashMap class. Try this one...!!!

MultiHashMap mp = new MultiHashMap();
mp.put("a", "1");
mp.put("b", "4");
mp.put("c", "2");
mp.put("a", "6");
List list = null;
Set set = mp.entrySet();
Iterator i = set.iterator();
while (i.hasNext()) {
        Map.Entry<String, List<String>> me = (Map.Entry) i.next();
        for(int j = 0 ; j< me.getValue().size(); j++ ){
        System.out.println(me.getKey() +" : " +me.getValue().get(j));
        }
    }
}
Akhilesh Dhar Dubey
  • 2,152
  • 2
  • 25
  • 39
  • 1
    This has been deprecated. MultiValueMap is the class to use, if going with Apache commons Collections. – PNS Feb 05 '14 at 19:51