Vassilis De Vassilis De - 1 month ago 12
Java Question

Java copy into a new list all lists (values) of Map<Integer, List<String>>

I have an issue with

Maps
.
Supposing we have the code below:

public class HashMaps {
public static void main(String[] ar){
List<String> list = new ArrayList<>();
Map<Integer, List<String>> myMap = new HashMap<>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
List cloneList = ((List) ((ArrayList) list).clone());
myMap.put(0, cloneList);
list.clear();
list.add("un");
list.add("deux");
list.add("trois");
list.add("quatre");
cloneList = ((List) ((ArrayList) list).clone());
myMap.put(1, cloneList);
System.out.println("map : "+myMap);
System.out.println("keys : "+myMap.keySet());
System.out.println("values : "+myMap.values());
}
}


How could I get into a new
List<String>
all values (
Lists
) of
myMap
?

Essentially, I have lists like:

["one"]
["two"]
["three"]
["four"]


And want to get:

["one","two","three","four"]

Answer

Based on your edit, it seems that you want to take each individual list in your Map and combine them into a single list:

List<String> combined = new ArrayList<String>();
for(List<String> list : myMap.values()) {
    combined.addAll(list);
}
// combined holds all lists into a single list

EDIT (based on your comment question)

If you want to add only certain lists, and not all of them, and the way you decide which ones is the index of list from the Map, then you can do it like this.

Convert the Collection returned by myMap.values() into a List and then use the list.get(index) method to add all values at allowed indexes.

List<String> selectedLists = new ArrayList<String>();
int[] allowedIndexes = {0, 1, 2, 3};                                          // only lists at indexes 0, 1, 2 and 3 are inserted into combined list
List<List<String>> listOfLists = new ArrayList<List<String>>(myMap.values()); // convert Collection to List
for(int i = 0; i < allowedIndexes.length; i++) {                              // if allowed index is within the bounds of the amount of lists, add the list at that index to selected lists
    int index = allowedIndexes[i];
    if(index < listOfLists.size()) {
        selectedLists.addAll(listOfLists.get(index));
    }
}
// selectedLists now contains only lists from the allowed indexes

A different approach would be to create an array of allowed indexes and iterate over all the values in the map, adding only the ones that correspond to an allowed index.

To determine if the current index is allowed, you can make a helper method that will iterate over all allowed indexes and check if current index exists as an allowed index.

Helper method:

// check if element exists in the array
boolean isInArray(int[] array, int element) {
    for(int i = 0; i < array.length; i++) {
        if(array[i] == element) {
            return true;
        }
    }
    return false;
}

Solution:

List<String> selectedLists = new ArrayList<String>();
int[] allowedIndexes = {0, 1, 2, 3};       // only lists at indexes 0, 1, 2 and 3 are inserted into combined list
int index = 0;                             // current index counter
for(List<String> list: myMap.values()) {   // iterate over all existing lists
    if(isInArray(allowedIndexes, index)) { // if the list at current index is allowed, add it to the selected lists
        selectedLists.addAll(list);
    }
    index++;                               // update the index
}
// selectedLists now contains only lists from the allowed indexes

One way you can improve the helper method, assuming you keep the array of allowed indexes sorted, is to use a Binary Search to check for existence of an index which would reduce the search time by a logarithmic factor:

boolean isInArrayImproved(int[] array, int element) {
    if(Arrays.binarySearch(array, element) >= 0) {
        return true;
    }
    return false;
}