我正在使用这段代码将一个Set转换为一个List:

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

for (int i=0; i < something.size(); i++) {
  Set<String> set = getSet(...); //returns different result each time
  List<String> listOfNames = new ArrayList<>(set);
  mainMap.put(differentKeyName, listOfNames);
}

我希望避免在循环的每次迭代中创建一个新列表。这可能吗?


当前回答

我们可以在Java 8中使用以下一行代码:

List<String> list = set.stream().collect(Collectors.toList());

这里有一个小例子:

public static void main(String[] args) {
        Set<String> set = new TreeSet<>();
        set.add("A");
        set.add("B");
        set.add("C");
        List<String> list = set.stream().collect(Collectors.toList());
}

其他回答

Java 8提供了使用流的选项,你可以从Set<String> setString中获得一个列表为:

List<String> stringList = setString.stream().collect(Collectors.toList());

尽管内部实现现在提供了一个ArrayList实例:

public static <T>
    Collector<T, ?, List<T>> toList() {
        return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
                                   (left, right) -> { left.addAll(right); return left; },
                                   CH_ID);
    }

但是JDK并不能保证它。如本文所述:

没有对类型、可变性、可序列化性或 返回List的线程安全;如果更多的控制返回 需要清单,使用收集(供应商)。

如果你想确保总是,那么你可以请求一个实例,具体为:

List<String> stringArrayList = setString.stream()
                     .collect(Collectors.toCollection(ArrayList::new));

您可以使用List.addAll()方法。它接受一个集合作为参数,您的集合就是一个集合。

List<String> mainList = new ArrayList<String>();
mainList.addAll(set);

编辑:作为对问题编辑的回应。 很容易看出,如果您想要有一个带有列表作为值的Map,为了有k个不同的值,您需要创建k个不同的列表。 因此:您根本无法避免创建这些列表,必须创建这些列表。

可能的解决方法: 声明你的Map为Map<String,Set>或Map<String,Collection>,然后插入你的Set。

我创建一个简单的静态方法:

public static <U> List<U> convertSetToList(Set<U> set)
{
    return new ArrayList<U>(set);
}

... 或者如果你想设置列表的类型,你可以使用:

public static <U, L extends List<U>> List<U> convertSetToList(Set<U> set, Class<L> clazz) throws InstantiationException, IllegalAccessException
{
    L list = clazz.newInstance();
    list.addAll(set);
    return list;
}

将Set转换为List而不添加排序信息(如排序),只是为了将其存储在映射中。

因为Set是无序的,没有添加任何排序信息,所以List不应该被使用,因为它将包含随机有序的数据,并且它的所有与有序数据相关的方法都是不明确的。

您应该使用Collection接口,它同时接受映射中的Set和List。这样,就不需要额外的内存,因为您使用多态而不是复制数据。

Map<String, Collection<String>> mainMap = new HashMap<>();

for (int i=0; i < something.size(); i++) {
  Set<String> set = getSet(...); //returns different result each time
  mainMap.put(differentKeyName, set);
}

免责声明:我对类似答案的编辑被拒绝了,所以我添加了自己的答案和额外的信息

我会这样做:

Map<String, Collection> mainMap = new HashMap<String, Collection>();

for(int i=0; i<something.size(); i++){
  Set set = getSet(...); //return different result each time
  mainMap.put(differentKeyName,set);
}