Java-8:Stream如何在Map上转换<k,list <d =“”>&gt;映射<d,列出<k =“”>&gt;

时间:2017-05-01 12:01:51

标签: java java-8 java-stream

我刚刚开始查看Java 8并试用lambdas,我有一个用于上述问题的用例,我使用通常的for循环来解决这个问题非常冗长且难以阅读

我现有的代码

private static Map<DataType, List<OperatorType>> buildmap() {

    Map<DataType, List<OperatorType>> map = Maps.newHashMap();

    for (OperatorType type : OperatorType.values()) {
        List<DataType> supportedTypes = type.getSupportedtypes();
        supportedTypes.forEach(datatype -> {
            if (map.containsKey(datatype)) {
                List<OperatorType> list = map.get(datatype);
                list.add(type);
                map.put(datatype,
                        list);
            } else {
                map.put(datatype,
                        new ArrayList<OperatorType>() {
                            private static final long serialVersionUID = 1L;

                            {
                                add(type);
                            }
                        });
            }
        });
    }

    return Collections.unmodifiableMap(new LinkedHashMap<>(map));
}

4 个答案:

答案 0 :(得分:4)

也许这样的事情会有所帮助:

<D, K> Map<D, List<K>> swap(Map<K, List<D>> map) {
  return map.entrySet().stream()
                       .flatMap(e -> e.getValue().stream()
                                                 .map(v -> new SimpleEntry<>(v, e.getKey())))
     .collect(Collectors.groupingBy(Entry::getKey, 
                                    Collectors.mapping(Entry::getValue,
                                                       Collectors.toList())));
}

Streams并不总是解决各种问题的最简单方法。有关更易理解且更简单的非流式解决方案,请参阅@Flown's answer

你也可以写出Flown的回答&#34; Stream-like&#34;使用.forEach,但它并没有真正获得更多可读性(假设values()getSupportedTypes()都返回List),我不推荐它只是说你正在使用流:

OperatorType.values()
  .forEach(type -> type.getSupportedTypes()
    .forEach(dataType -> map.computeIfAbsent(dataType, dt -> new ArrayList<>())
                                                .add(type)));

答案 1 :(得分:2)

Stream解决方案需要一些flatmapping和元组创建。

你应该坚持使用嵌套循环。

private static Map<DataType, List<OperatorType>> buildmap() {
  Map<DataType, List<OperatorType>> map = new HashMap<>();

  for (OperatorType type : OperatorType.values()) {
    for (DataType dataType : type.getSupportedTypes()) {
      map.computeIfAbsent(dataType, dt -> new ArrayList<>()).add(type);
    }
  }

  map.replaceAll((dt, ot) -> Collections.unmodifiableList(ot));

  return Collections.unmodifiableMap(map);
}

答案 2 :(得分:1)

由于您似乎正在使用Guava,您可以使用它们的展平多图集合器,将其反转并返回地图视图:

private static Map<DataType, List<OperatorType>> buildmap() {
    ImmutableListMultimap<OperatorType, DataType> flattened =
            Arrays.stream(OperatorType.values())
                    .collect(ImmutableListMultimap.flatteningToImmutableListMultimap(
                            Function.identity(),
                            o -> o.getSupportedtypes().stream()));
    return Multimaps.asMap(flattened.inverse());
}

答案 3 :(得分:-1)

以下是StreamEx

的简单解决方案
read -p "what is in:" in
read -p "what is out:" out
read -p "what is char num:" char

grep -oP '\b(\w{$char})\b' $in >> $out