Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have one HashMap<String, ArrayList<String>> and I want to concatenate a key with every item in its ArrayList.

Consider the following demo program:

HashMap<String, ArrayList<String>> map1 = new HashMap<String, ArrayList<String>>();

        ArrayList<String> map11 = new ArrayList<String>();
        map11.add("a");
        map11.add("b");
        map1.put("1", map11);

        ArrayList<String> map12 = new ArrayList<String>();
        map12.add("c");
        map12.add("d");
        map1.put("2", map12);

ArrayList<String> finalList = new ArrayList<String>();
        for (Entry<String, ArrayList<String>> ent : map1.entrySet()) {
            ArrayList<String> ls = ent.getValue();
            for (String string : ls) {
                finalList.add(ent.getKey()+" = "+string);
            }
        }

This is working fine and giving expected output. The value of finalList after executing program is:

[1 = a, 1 = b, 2 = c, 2 = d]

If there is any better and faster way to do this, please let me know. In the actual project ArrayList, every HashMap entry contains thousands of items.

share|improve this question
    
Do you really need a List as the result? Are you planning to serialize it? Do you need to know the total size? If not, you could consider implementing a custom Iterable. – Robby Cornelissen Nov 21 '14 at 9:24
    
yes I need list. But for knowledge can you give me link where I can find example of custom iterable – DCoder Nov 21 '14 at 10:42
up vote 3 down vote accepted

If it's really a list of entries that you want, then this is about as fast as it gets.

But it can be better:

  • Use interface types instead of implementations, for example List instead of ArrayList and Map instead of HashMap
  • Java 6 is no longer supported, and in Java 7 you should use the diamond operator to create new instances, for example: Map<String, List<String>> map1 = new HashMap<>();
  • Use better, more natural names, for example:
    • entry is better than ent
    • list is better than ls
  • Use unit tests to verify your implementation

Based on the above, here's an alternative implementation:

public static List<String> concatMapEntries(Map<String, List<String>> map) {
    List<String> finalList = new ArrayList<>();
    for (Map.Entry<String, List<String>> entry : map.entrySet()) {
        List<String> list = entry.getValue();
        for (String string : list) {
            finalList.add(entry.getKey() + " = " + string);
        }
    }
    return finalList;
}

And unit test:

@Test
public void testExample() {
    Map<String, List<String>> map1 = new HashMap<>();

    List<String> map11 = new ArrayList<>();
    map11.add("a");
    map11.add("b");
    map1.put("1", map11);

    List<String> map12 = new ArrayList<>();
    map12.add("c");
    map12.add("d");
    map1.put("2", map12);

    assertEquals("[1 = a, 1 = b, 2 = c, 2 = d]", concatMapEntries(map1).toString());
}
share|improve this answer
    
you said Use interface types instead of implementations, for example List instead of ArrayList and Map instead of HashMap what is reason behind it? – DCoder Nov 21 '14 at 7:37
    
It's better to code against the most generic interface possible. For example the alternative implementation I gave you will work with a TreeMap with LinkedList values too, making it far more usable than the original. – janos Nov 21 '14 at 7:47

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.