入门级集上的 Java 8 流映射

2022-08-31 13:05:17

我正在尝试对对象中的每个条目执行映射操作。Map

我需要从键上取下前缀,并将值从一种类型转换为另一种类型。我的代码是从 a 获取配置条目并转换为 a ( 只是一个包含一些信息的类。进一步的解释与这个问题无关。Map<String, String>Map<String, AttributeType>AttributeType

我使用Java 8 Streams所能想到的最好的是:

private Map<String, AttributeType> mapConfig(Map<String, String> input, String prefix) {
   int subLength = prefix.length();
   return input.entrySet().stream().flatMap((Map.Entry<String, Object> e) -> {
      HashMap<String, AttributeType> r = new HashMap<>();
      r.put(e.getKey().substring(subLength), AttributeType.GetByName(e.getValue()));
      return r.entrySet().stream();
   }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}

由于它是一个接口而无法构造 ,导致创建单个条目实例并使用 ,这似乎很丑陋。Map.EntryMapflatMap()

有没有更好的选择?使用 for 循环执行此操作似乎更好:

private Map<String, AttributeType> mapConfig(Map<String, String> input, String prefix) {
   Map<String, AttributeType> result = new HashMap<>(); 
   int subLength = prefix.length(); 
   for(Map.Entry<String, String> entry : input.entrySet()) {
      result.put(entry.getKey().substring(subLength), AttributeType.GetByName( entry.getValue()));
   }
   return result;
}

我应该为此避免使用流 API 吗?还是有我没有错过的更好的方式?


答案 1

简单地将“旧的 for 循环方式”转换为流:

private Map<String, String> mapConfig(Map<String, Integer> input, String prefix) {
    int subLength = prefix.length();
    return input.entrySet().stream()
            .collect(Collectors.toMap(
                   entry -> entry.getKey().substring(subLength), 
                   entry -> AttributeType.GetByName(entry.getValue())));
}

答案 2

请使收集器 API 的以下部分:

<K, V> Collector<? super Map.Entry<K, V>, ?, Map<K, V>> toMap() {
  return Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue);
}

推荐