将地图中的列表展平为单个列表

时间:2017-11-10 13:52:02

标签: java list hashmap

我已定义了map,如下所示,它有字符串列表作为值

Map<Integer,List<String>> MapOf_words_arrays = new HashMap<Integer,List<String>>();

我需要将上面Map的值放到一个字符串数组中(如下所示),。

["dog","cat"]
["book","pen","phone","waterbottle"]
.
.
.etc

我正在使用以下声明

String wordlists = MapOf_words_arrays.values().toArray(new String[0]);

但我收到了错误

  

线程“main”中的异常java.lang.ArrayStoreException:   java.util.ArrayList中的$ SUBLIST           at java.util.AbstractCollection.toArray(AbstractCollection.java:196)           在ScrapePages.main(ScrapePages.java:98)

有人可以帮助我吗?

7 个答案:

答案 0 :(得分:2)

说明

ArrayStoreException表示您尝试将错误类型元素存储到错误类型的数组中(请参阅其documentation)。

您正在致电

values().toArray(new String[0])

因此,您尝试将某些内容存储到一个接受String作为其元素的数组中。但是,Map#values在您的情况下不会返回String,而是返回包含Collection类型元素的List<String>。这就是为什么它想要一个List类型的数组,而不是String

解决方案

您首先需要将所有子列表展平为一个。为此,您有多种选择。最直接的解决方案是迭代所有元素,然后将它们添加到另一个List,然后转换此列表数组

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);

或更紧凑,使用Stream的解决方案( Java 8 ):

String[] result = MapOf_words_arrays.values().stream()  // List<String>
    .flatMap(List::stream)                              // String
    .toArray(String[]::new)

答案 1 :(得分:1)

您可以通过从地图值创建迭代器来实现。然后使用while循环遍历所有值并从列表中获取所有字符串并将它们添加到单个 ArrayList 并将其转换为String []。 :)

以下是代码:

Vagrant.configure("2") do |config|
  config.vm.network "private_network", type: "dhcp"
end

答案 2 :(得分:1)

试试这个:

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

答案 3 :(得分:0)

以下是将Map<Integer, List<String>>转换为List<String>String[]的方式。

注意:最后,使用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));
    }
}

示例运行:

[11, 12, 13, 21, 22, 23]
[11, 12, 13, 21, 22, 23]
[11, 12, 13, 21, 22, 23]
[11, 12, 13, 21, 22, 23]

答案 4 :(得分:0)

以下是您想要的完整工作演示

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]+" ");



    }
}

答案 5 :(得分:0)

如果可以,请考虑优雅的Java 8解决方案。

// 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);

答案 6 :(得分:0)

以下是使用Java 8功能的方法(但没有流的开销):

List<String> result = new ArrayList<>();
mapOfWordsArrays.values().forEach(result::addAll);

这会迭代地图的所有值,并将每个值(类型为List<String>)添加到result列表中。这就是我使用List.addAll方法的原因。

另一种方法是直接迭代地图的条目:

List<String> result = new ArrayList<>();
mapOfWordsArrays.forEach((k, v) -> result.addAll(v));

IMO,这是最紧凑,最易读和最简单的方式。

我建议您查看List.addAllIterable.forEachMap.forEach方法的文档以获取更多详细信息。

注意:我已经更改了变量名称以坚持Java命名约定。