将值从map转换为set

时间:2018-05-10 13:55:54

标签: java collections hashset

我有一个字符串映射到字符串Map<String, List<String>>的列表 这是从地图中的值

创建集合的最有效方法
for (List<String> localList : map.values()) {
    set.addAll(localList);
}

2 个答案:

答案 0 :(得分:3)

取决于“最有效的方式”的含义。

从性能角度来看,您的代码效率最高。

使用Java 8 Streams可以简化代码,但性能会有所下降,但是在宏观方案中不太可能引人注意,因此Streams可能“效率更高”。

然而,这主要是一个更好的意见问题。

为了比较,您的代码:

Set<String> set = new HashSet<>();
for (List<String> localList : map.values()) {
    set.addAll(localList);
}

与Stream版本相比:

Set<String> set = map.values().stream().flatMap(List::stream).collect(Collectors.toSet());

为了便于阅读,可以写成:

Set<String> set = map.values()
                     .stream()
                     .flatMap(List::stream)
                     .collect(Collectors.toSet());

如果您想控制Set的类型,请将最后一部分更改为:

                     .collect(Collectors.toCollection(TreeSet::new));

答案 1 :(得分:0)

我认为你的性能是最有效的方式的关键。在这种情况下,简单的基准可以提供最佳答案。这是一个简单的JMH基准:

package test;

import org.openjdk.jmh.annotations.*;

import java.util.*;
import java.util.stream.Collectors;

public class ListOfStringsToSetBenchmark {

    public static void main(String[] args) throws Exception {
        org.openjdk.jmh.Main.main(args);
    }

    @Benchmark
    @Fork(value = 1, warmups = 1)
    @Measurement(iterations = 5)
    @Warmup(iterations = 3)
    @BenchmarkMode(Mode.Throughput)
    public void streams() {
        Map<String, List<String>> map = new HashMap<>();

        map.put("test", Arrays.asList("1", "2", "3"));
        map.put("test2", Arrays.asList("4", "5", "6"));
        map.put("test3", Arrays.asList("7", "8", "9"));

        Set<String> collect = map.values().stream().flatMap(Collection::stream).collect(Collectors.toSet());
    }

    @Benchmark
    @Fork(value = 1, warmups = 1)
    @Measurement(iterations = 5)
    @Warmup(iterations = 3)
    @BenchmarkMode(Mode.Throughput)
    public void parallelStreams() {
        Map<String, List<String>> map = new HashMap<>();

        map.put("test", Arrays.asList("1", "2", "3"));
        map.put("test2", Arrays.asList("4", "5", "6"));
        map.put("test3", Arrays.asList("7", "8", "9"));

        Set<String> collect = map.values().parallelStream().flatMap(Collection::parallelStream).collect(Collectors.toSet());
    }

    @Benchmark
    @Fork(value = 1, warmups = 1)
    @Measurement(iterations = 5)
    @Warmup(iterations = 3)
    @BenchmarkMode(Mode.Throughput)
    public void forEach() {
        Map<String, List<String>> map = new HashMap<>();

        map.put("test", Arrays.asList("1", "2", "3"));
        map.put("test2", Arrays.asList("4", "5", "6"));
        map.put("test3", Arrays.asList("7", "8", "9"));

        Set<String> set = new HashSet<>();

        for (List<String> localList : map.values()) {
            set.addAll(localList);
        }
    }
}

<强>结果

Benchmark                              Mode  Cnt        Score        Error  Units
ListOfStringsToSetBenchmark.forEach          thrpt    5  5290023,805 ±  89846,320  ops/s
ListOfStringsToSetBenchmark.parallelStreams  thrpt    5   588714,960 ±   6289,819  ops/s
ListOfStringsToSetBenchmark.streams          thrpt    5  2940686,522 ± 359335,288  ops/s

注意:为了获得精确的结果,您需要增加迭代值。