Wil*_*ood 45 java lambda dictionary java-8
我正在尝试对Map
对象中的每个条目执行映射操作.
我需要从键中取一个前缀并将值从一种类型转换为另一种类型.我的代码从a获取配置条目Map<String, String>
并转换为a 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));
}
Run Code Online (Sandbox Code Playgroud)
Map.Entry
由于它是一个接口而无法构造,导致单个条目Map
实例的创建和使用flatMap()
,这看起来很难看.
还有更好的选择吗?使用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;
}
Run Code Online (Sandbox Code Playgroud)
我应该为此避免使用Stream API吗?还是我错过了一个更好的方式?
Smu*_*tje 100
只需将"旧的循环方式"转换为流:
private Map<String, String> mapConfig(Map<String, Integer> input, String prefix) {
return input.entrySet().stream()
.collect(Collectors.toMap(
entry -> entry.getKey().substring(subLength),
entry -> AttributeType.GetByName(entry.getValue())));
}
Run Code Online (Sandbox Code Playgroud)
小智 18
问题可能有点过时,但您可以简单地使用AbstractMap.SimpleEntry <>,如下所示:
private Map<String, AttributeType> mapConfig(
Map<String, String> input, String prefix) {
int subLength = prefix.length();
return input.entrySet()
.stream()
.map(e -> new AbstractMap.SimpleEntry<>(
e.getKey().substring(subLength),
AttributeType.GetByName(e.getValue()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Run Code Online (Sandbox Code Playgroud)
任何其他类似于对象的值对象也会起作用(即ApacheCommons Pair元组).
小智 16
请制作Collectors API的以下部分:
<K, V> Collector<? super Map.Entry<K, V>, ?, Map<K, V>> toMap() {
return Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue);
}
Run Code Online (Sandbox Code Playgroud)
在 Java 9 或更高版本上,Map.entry
可以使用,只要您知道键和值都不为空。如果任何一个值都可以合法地为空AbstractMap.SimpleEntry
(如另一个答案中所建议的那样),或者AbstractMap.SimpleImmutableEntry
将是一个很好的方法。
private Map<String, AttributeType> mapConfig(Map<String, String> input, String prefix) {
int subLength = prefix.length();
return input.entrySet().stream().map(e ->
Map.entry(e.getKey().substring(subLength), AttributeType.GetByName(e.getValue()))
).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
Run Code Online (Sandbox Code Playgroud)
话虽如此,在这种特殊情况下,临时Entry
对象中没有真正的价值,并且在其中执行键/值映射会更惯用Collectors.toMap
(如另一个答案中所示)。但是,创建临时条目对象是有正当理由的,因此了解它仍然很有帮助。
归档时间: |
|
查看次数: |
95235 次 |
最近记录: |