Home > front end >  Converting a Map with List values into a List in Java
Converting a Map with List values into a List in Java

Time:04-17

I have a Map<Double, List<String>> that contains the following elements:

{1.0=[AP], 2.2=[AB], 2.5=[AC], 3.5=[AD], 4.5=[AE, AF], 6.30000000000001=[AG]}

I wish to add these elements into a List so that it would print out like so or print them out like so:

[AP 1.0, AB 2.2, AC 2.5, AD 3.5 , AE 4.5, AF 4.5, AG 6.3] 

How would I go about doing this?

I have tried the following

Map<Double, List<String>> mapToPopulate = new TreeMap<Double, List<String>>();
List <String> output = new ArrayList<>();

// after populating map
 for(Double d: mapToPopulate .keySet()) {
     result.add(mapToPopulate.get(d)   " "   d);}

but it prints it out in this form

[[AP] 1.0,[AB] 2.2,[AC] 2.5,[AD] 3.5, [AE, AF] 4.5,[AG] 6.30000000000001]

CodePudding user response:

I notice, that here you are directly fetching the list and appending the value to it, and storing it in the list.

After populating the map, you can use the following code to generate the result that you expect.

// After populating map
List<String> result = mapToPopulate.entrySet()
            .stream()
            .flatMap(en -> en.getValue().stream().map(v -> v   " "   en.getKey()))
            .collect(Collectors.toList());

CodePudding user response:

Since you want to add every string in a list mapped to a particular key as a separate item concatenated with its key into the resulting list, you need to iterate over each list of values (in your code you've concatenated a string representation of a list instead).

You can do that by adding a nested loop.

And it's better to establish iteration in the outer loop over the entry set. Because each entry holds a direct reference to the value and allows accessing it almost instantly (in O(1) time). Meanwhile, accessing a value mapped to a particular key with a method get() will require additional actions even if you were using a HashMap, and for a TreeMap method get() is way more slower and performs in O(n) time. Therefore, this change can significantly improve performance.

The code might look like this:

public static void main(String[] args) {
    Map<Double, List<String>> source =
        Map.of(1.0, List.of("AP"), 2.2, List.of("AB"), 2.5, List.of("AC"),
            3.5, List.of("AD"), 4.5, List.of("AE", "AF"), 6.30000000000001, List.of("AG"));
    
    NavigableMap<Double, List<String>> mapToPopulate = new TreeMap<>(source);
    List<String> result = new ArrayList<>();
    
    for (Map.Entry<Double, List<String>> entry : mapToPopulate.entrySet()) {
        for (String value : entry.getValue())
            result.add(entry.getKey()   " "   value);
    }

    System.out.println(result);
}

Output

[1.0 AP, 2.2 AB, 2.5 AC, 3.5 AD, 4.5 AE, 4.5 AF, 6.30000000000001 AG]

Sidenote:

  • When using a TreeMap, if you don't expect the variable that hold reference to it to be assigned with an unsorted implementation of the Map interface, it's better to utilize NavigableMap interface as type. It'll give you access to such methods like firstEntry(), firstKey(), higherKey(), headMap(), etc. that are not available with Map interface.
  • Related