遍历目录后Map存值遇重复键丢失数据:如何实现多值关联输出
解决Map重复键覆盖问题,实现多项目多类的完整输出
这问题我太熟了!Map的键唯一性刚好在这个场景下拖了后腿——你需要的是一个项目对应多个类,而不是一个项目只存最后一个类。解决思路很直接:把原来的单值Map换成键对应列表的多值Map就行,具体操作如下:
1. 调整Map的类型定义
把原来的Map<String, String>(假设你之前是这么定义的)改成Map<String, List<String>>,这样每个项目名称(比如kata、emacs4ij)对应的不再是单个类名,而是一个可以容纳多个类名的列表。
示例代码:
// 替换原来的单值Map,用HashMap存储项目名和对应类名列表 private Map<String, List<String>> projectClassMap = new HashMap<>();
2. 修改文件遍历的逻辑
在visitFile方法中,处理每个文件时,不要直接用put方法覆盖值,而是把当前类名添加到对应项目的列表中。这里可以用Java 8+提供的computeIfAbsent方法简化代码,它会自动处理“键不存在则创建新列表”的逻辑:
@Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { // 这里假设你已经有逻辑能从文件路径中解析出项目名和类名 String projectName = extractProjectName(file); // 比如从路径得到"kata" String className = extractClassName(file); // 比如得到"FizzBuzz" // 核心操作:如果项目名不在Map中,就创建新的ArrayList;否则直接用已有列表,添加当前类名 projectClassMap.computeIfAbsent(projectName, k -> new ArrayList<>()).add(className); return FileVisitResult.CONTINUE; }
如果你还在用Java 8之前的版本,也可以手动写判断逻辑:
if (!projectClassMap.containsKey(projectName)) { projectClassMap.put(projectName, new ArrayList<>()); } projectClassMap.get(projectName).add(className);
3. 按预期格式打印结果
遍历这个多值Map的entrySet,逐个输出项目名和对应的每个类名,就能得到你想要的完整输出:
public void printFinalResult() { // 先输出开头的"project class" System.out.println("project class"); // 遍历每个项目及其类列表 for (Map.Entry<String, List<String>> entry : projectClassMap.entrySet()) { String project = entry.getKey(); for (String clazz : entry.getValue()) { System.out.printf("%s %s%n", project, clazz); } } }
这样处理后,每个项目下的所有类都会被保留,不会再出现被最后一个值覆盖的情况,最终输出就会和你预期的一致:
project class kata FizzBuzz kata FizzBuzzTest kata Anagrams kata AnagramsTest emacs4ij BufferTest emacs4ij TestSetup emacs4ij TestFrameManagerImp
内容的提问来源于stack exchange,提问作者Skipper07
相关产品推荐
相关产品推荐

