我一直在努力学习Java 8的新功能接口功能,而且我在重构之前编写的代码时遇到了一些困难。
作为测试用例的一部分,我想在Map结构中存储一个读取名称列表,以便检查这些读取是否已被修复"在随后的代码部分中。我正在转换现有的地图>数据结构。我之所以将这个数据结构弄平,是因为外部" String"在后续分析中不需要原始Map的关键字(我在将它们合并到中间数据之前用它来隔离来自不同源的数据)。这是我原来的程序逻辑:
public class MyClass {
private Map<String, Map<String, Short>> anchorLookup;
...
public void CheckMissingAnchors(...){
Map<String, Boolean> anchorfound = new HashMap<>();
// My old logic used the foreach syntax to populate the "anchorfound" map
for(String rg : anchorLookup.keySet()){
for(String clone : anchorLookup.get(rg).keySet()){
anchorfound.put(clone, false);
}
}
...
// Does work to identify the read name in the file. If found, the boolean in the map
// is set to "true." Afterwards, the program prints the "true" and "false" counts in
// the map
}
}
我试图重构代码以使用功能接口;但是,我从IDE(运行Java 1.8.0_05的Netbeans 8.0 Patch 2)中收到错误:
public class MyClass {
private Map<String, Map<String, Short>> anchorLookup;
...
public void CheckMissingAnchors(...){
Map<String, Boolean> anchorfound = anchorLookup.keySet()
.stream()
.map((s) -> anchorlookup.get(s).keySet()) // at this point I am expecting a
// Stream<Set<String>> which I thought could be "streamed" for the collector method
// ; however, my IDE does not allow me to select the "stream()" method
.sequential() // this still gives me a Stream<Set<String>>
.collect(Collectors.toMap((s) -> s, (s) -> false);
// I receive an error for the preceding method call, as Stream<Set<String>> cannot be
// converted to type String
...
}
}
是否有更好的方法来创建&#34; anchorfound&#34;使用Collection方法映射或者是vanilla Java&#34; foreach&#34;结构生成这种数据结构的最佳方法是什么?
我为代码中的任何明显错误道歉。我的正式培训不是计算机科学,但我想更多地了解Java的函数式编程概念的实现。
答案 0 :(得分:4)
我相信你需要的是一个flatMap。
这样,您可以将外部地图的每个键转换为相应内部地图的键的流,然后将它们展平为单个String流。
public class MyClass {
private Map<String, Map<String, Short>> anchorLookup;
...
public void CheckMissingAnchors(...){
Map<String, Boolean> anchorfound = anchorLookup.keySet()
.stream()
.flatMap(s -> anchorlookup.get(s).keySet().stream())
.collect(Collectors.toMap((s) -> s, (s) -> false);
...
}
}
答案 1 :(得分:4)
flatMap
的{{3}}是一个很好的,+ 1。
使用Map.values()
代替Map.keySet()
可以稍微简化一下,因为地图的密钥并不用于检索值以外的任何其他目的。流式传输Map.values()
的结果会得到Stream<Map<String,Short>>
。在这里,我们不关心内部地图的值,因此我们可以使用keySet()
提取密钥,并提供Stream<Set<String>>
。现在我们只需flatMap
将这些集合放入Stream<String>
。最后,我们像以前一样将结果发送到收集器。
结果代码如下所示:
public class MyClass {
private Map<String, Map<String, Short>> anchorLookup;
public void checkMissingAnchors() {
Map<String, Boolean> anchorfound = anchorLookup.values().stream()
.map(Map::keySet)
.flatMap(Set::stream)
.collect(Collectors.toMap(s -> s, s -> false));
}
}