如何将“List type的Hashmap值”转换为Set?

时间:2016-09-20 12:33:35

标签: java list collections hashmap guava

如何在Map中连接“值列表”以创建单个列表然后传递到另一个方法:

Map<Long,List<Long>> activities = new HashMap();
for(Something s: something){
  activities .put(prosessLongID, listOfSubProcesses);
} //There are 5 something and for each there are 2 List of Subprocesses which makes 10 Subprocesses

我想从上面的Map中连接Subprocesses列表以创建Set:

 ImmutableSet.copyOf(listOfSubProcesses_ForAllSomething) //com.google.common.collect

Map中是否有任何方法返回单个列表中的所有SubProcesses列表,我可以在上面的方法中传递?

注意:我在Java 8上得到了@Eran的回复并感谢您的支持。但请考虑Java 6和解决方案,然后循环。我有APache Commons和Guava的设施。 :)

2 个答案:

答案 0 :(得分:4)

如果您不能使用Java 8 Stream,请使用Guava的FluentIterable(和Map#values()作为评论中提到的@Lukas):

ImmutableSet<Long> subprocessIds = FluentIterable.from(activities.values())
        .transformAndConcat(Functions.identity())
        .toSet();

FluentIterable#transformAndConcat相当于Stream#flatMap,身份函数实际上没有任何效果,因此它直接从@Eran的Java 8答案转换为Guava和Java 7。

或者,您可以使用Iterables#concat来获得相同的结果而无需流畅的调用:

ImmutableSet<Long> subprocessIds = ImmutableSet.copyOf(
        Iterables.concat(activities.values()));

您真正想要做的是使用正确的数据结构,在这里:ListMultimap(或者甚至可能SetMultimap?):

ListMultimap<Long, Long> activities = ArrayListMultimap.create();
activities.putAll(1L, ImmutableList.of(2L, 32L, 128L));
activities.put(3L, 4L);
activities.put(3L, 8L);

因为Multimap#values()为您提供了所需内容(如Collection视图所示,因此如果需要,请复制到Set):

ImmutableSet<Long> subprocessIds = ImmutableSet.copyOf(activities.values());

答案 1 :(得分:1)

您可以使用Java 8 Streams API将所有List收集到一个Stream中,然后收集到一个List中:

List<Long> listOfSubProcesses_ForAllSomething = 
    activities.values().stream().flatMap(List::stream).collect(Collectors.toList());