Reputation: 31
I have defined a map
like below and it has lists of strings as values
Map<Integer,List<String>> MapOf_words_arrays = new HashMap<Integer,List<String>>();
I need to get the values of above Map in to one string array (e.g shown below) , .
["dog","cat"]
["book","pen","phone","waterbottle"]
.
.
.etc
I'm using the below statement
String wordlists = MapOf_words_arrays.values().toArray(new String[0]);
but I'm getting an error
Exception in thread "main" java.lang.ArrayStoreException: java.util.ArrayList$SubList at java.util.AbstractCollection.toArray(AbstractCollection.java:196) at ScrapePages.main(ScrapePages.java:98)
Can anybody help me out here?
Upvotes: 3
Views: 3827
Reputation: 34480
Here's a way to do it with Java 8 features (but without the overhead of streams):
List<String> result = new ArrayList<>();
mapOfWordsArrays.values().forEach(result::addAll);
This iterates over all the values of the map, and adds each value (which is of type List<String>
) to the result
list. This is why I'm using the List.addAll
method.
Another way would be to iterate directly on the entries of the map:
List<String> result = new ArrayList<>();
mapOfWordsArrays.forEach((k, v) -> result.addAll(v));
IMO, this is the most compact, yet readable and easiest way.
I suggest you check the docs of List.addAll
, Iterable.forEach
and Map.forEach
methods for further details.
Note: I've changed the variables names to stick to Java naming conventions.
Upvotes: 0
Reputation: 311
Try this:
ArrayList<String> allStrings = new ArrayList<>();
for (List<String> list : MapOf_words_arrays.values()) {
allStrings.addAll(list);
}
String[] stringArray = allStrings.toArray(new String[] {}); //The array you wanted
Upvotes: 1
Reputation: 25943
ArrayStoreException
means that you are trying to store the wrong type of elements into the wrong type of array (see its documentation).
You are calling
values().toArray(new String[0])
So you try to store something into an array which accepts String
as its elements. However Map#values
doesn't return String
in your case, it returns a Collection
containing elements of type List<String>
. That's why it wants an array of type List
, not String
.
You first need to flatten all sub-lists into one. For this you have multiple options. The most straight-forward solution would be to iterate all elements and then add them into another List
, then convert this list into an array:
List<String> valuesFlatten = new ArrayList<>();
// Flatten all values
for (List<String> valueContainer : MapOf_words_arrays.values()) {
valuesFlatten.addAll(valueContainer);
}
// Create and fill the array
String[] result = new String[valuesFlatte.size()];
valuesFlatten.toArray(result);
Or more compact, a solution using Stream
s (Java 8):
String[] result = MapOf_words_arrays.values().stream() // List<String>
.flatMap(List::stream) // String
.toArray(String[]::new)
Upvotes: 5
Reputation: 2506
Please consider an elegant Java 8 solution, if you can.
// compute the size of the target array
int size = map.values().stream().reduce(0,(k, l) -> k+l.size(), (l,r) ->l+r);
// allocate the target array
String[] test = new String[size];
// reduce the map to a list (this is in general more efficient than directly reducing it to an array)
map.values().stream().reduce(
new ArrayList<String>(),
(l, x) -> {l.addAll(x); return l;}
).toArray(test);
// test output that everything worked
for (String s:test)
System.out.println(s);
Upvotes: 0
Reputation: 4187
Here is how you can convert Map<Integer, List<String>>
to either List<String>
or String[]
.
NOTE: at the end, checkout out the simplest way to convert it using Java 8 Streams
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class MapClass {
public static void main(String[] args) {
Map<Integer, List<String>> map = new HashMap<Integer, List<String>>();
map.put(1, Arrays.asList("11", "12", "13"));
map.put(2, Arrays.asList("21", "22", "23"));
// if you need list
List<String> result = new ArrayList<String>();
for (List<String> list : map.values()) {
result.addAll(list);
}
System.out.println(result);
// if you need array
String[] array = result.toArray(new String[0]);
System.out.println(Arrays.toString(array));
// using streams
List<String> java8List = map
.values()
.stream()
.flatMap(l -> l.stream())
.collect(Collectors.toList());
System.out.println(java8List);
// if you need array
String[] arrays = java8List.toArray(new String[0]);
System.out.println(Arrays.toString(arrays));
}
}
Sample Run:
[11, 12, 13, 21, 22, 23]
[11, 12, 13, 21, 22, 23]
[11, 12, 13, 21, 22, 23]
[11, 12, 13, 21, 22, 23]
Upvotes: 0
Reputation: 310
Here is the full working demo of what you wanted
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
Map<Integer,List<String>> MapOf_words_arrays = new HashMap<Integer,List<String>>();
ArrayList<String> s1=new ArrayList<>();
s1.add("anupam");
s1.add("lucky");
ArrayList<String> s2=new ArrayList<>();
s2.add("anu");
s2.add("luck");
MapOf_words_arrays.put(0,s1);
MapOf_words_arrays.put(1,s2);
ArrayList<String> final_ans=new ArrayList<String>();
for(List<String> list : MapOf_words_arrays.values())
{
for(int i=0;i<list.size();i++)
{
final_ans.add(list.get(i));
}
}
String[] myArray = final_ans.toArray(new String[final_ans.size()]);
for(int b=0;b<myArray.length;b++)
System.out.print(myArray[b]+" ");
}
}
Upvotes: 0
Reputation: 436
You can do it by creating a Iterator from the map values. Then iterate through all values using the while loop and get all Strings from the lists and add them to a single ArrayList and convert it to String[]. :)
Here is working the code:
Map<Integer,List<String>> MapOf_words_arrays = new HashMap<Integer,List<String>>();
Iterator<List<String>> iterator = MapOf_words_arrays.values().iterator();
ArrayList<String> data = new ArrayList<String>();
List<String> tempList;
while(iterator.hasNext()){
tempList = iterator.next();
for(String item: tempList){
data.add(item);
}
}
// Here is your array with all strings.
String[] array = data.toArray(new String[]{});
Upvotes: 1