【问题标题】:How to Loop next element in hashmap如何循环哈希图中的下一个元素
【发布时间】:2017-01-17 15:28:33
【问题描述】:

我有一组这样的字符串

A_2007-04, A_2007-09, A_Agent, A_Daily, A_Execute, A_Exec, B_Action, B_HealthCheck

我想输出为:

Key = A, Value = [2007-04,2007-09,Agent,Execute,Exec]
Key = B, Value = [Action,HealthCheck]

我正在使用 HashMap 来执行此操作

pckg:{A,B}
count:total no of strings
reports:set of strings

我使用的逻辑是嵌套循环:

for (String l : reports[i]) {
    for (String r : pckg) {
        String[] g = l.split("_");
        if (g[0].equalsIgnoreCase(r)) {
            report.add(g[1]);
            dirFiles.put(g[0], report);
        } else {
            break;
        }
    }
}

我得到的输出为

Key = A, Value = [2007-04,2007-09,Agent,Execute,Exec]

如何获得第二把钥匙? 有人可以为此提出逻辑吗?

【问题讨论】:

  • pckg的值是多少?
  • 首先,您的变量名称令人困惑。你应该给他们起有意义的名字。二、pckg的类型是什么?在 reports[i] 的 for 循环中循环 pckg 变量似乎很奇怪@
  • 用 P_Action 和 P_HealthCheck,你不能得到 Key = B, Value = [Action,HealthCheck],你只能用 Key = P 得到它,所以 pckg 应该是:{A,P} 而不是 {A ,B}

标签: java for-loop hashmap


【解决方案1】:

假设您使用Java 8,可以使用computeIfAbsent来初始化值的List,当它是一个新的key时:

List<String> tokens = Arrays.asList(
    "A_2007-04", "A_2007-09", "A_Agent", "A_Daily", "A_Execute", 
    "A_Exec", "P_Action", "P_HealthCheck"
);
Map<String, List<String>> map = new HashMap<>();
for (String token : tokens) {
    String[] g = token.split("_");
    map.computeIfAbsent(g[0], key -> new ArrayList<>()).add(g[1]);
}

【讨论】:

  • +1 提醒我注意 computeIfAbsent。一段时间以来,我一直想知道为什么 Java 核心没有让处理一个其值本身就是一个集合的映射变得更容易,而这很好地填补了这一空白。
【解决方案2】:

就原始代码而言,这应该可以实现我认为您正在努力实现的目标:

// Create a collection of String any way you like, but for testing
// I've simply split a flat string into an array.
String flatString = "A_2007-04,A_2007-09,A_Agent,A_Daily,A_Execute,A_Exec,"
        + "P_Action,P_HealthCheck";
String[] reports = flatString.split(",");

Map<String, List<String>> mapFromReportKeyToValues = new HashMap<>();

for (String report : reports) {
    int underscoreIndex = report.indexOf("_");
    String key = report.substring(0, underscoreIndex);
    String newValue = report.substring(underscoreIndex + 1);
    List<String> existingValues = mapFromReportKeyToValues.get(key);
    if (existingValues == null) {
        // This key hasn't been seen before, so create a new list
        // to contain values which belong under this key.
        existingValues = new ArrayList<>();
        mapFromReportKeyToValues.put(key, existingValues);
    }
    existingValues.add(newValue);
}

System.out.println("Generated map:\n" + mapFromReportKeyToValues);

虽然我建议将其整理并组织成适合您项目代码的一个或多个方法。

【讨论】:

    【解决方案3】:

    我认为使用Map&lt;String, ArrayList&lt;String&gt;&gt; 执行此操作将是另一种好方法:

        String reports[] = {"A_2007-04", "A_2007-09", "A_Agent", "A_Daily", 
                            "A_Execute", "A_Exec", "P_Action", "P_HealthCheck"};
        Map<String, ArrayList<String>> map = new HashMap<>();
    
        for (String rep : reports) {
    
            String s[] = rep.split("_");
            String prefix = s[0], suffix = s[1];
            ArrayList<String> list = new ArrayList<>();
    
            if (map.containsKey(prefix)) {
                list = map.get(prefix);
            }
    
            list.add(suffix);
            map.put(prefix, list);
        }
    
        // Print
        for (Map.Entry<String, ArrayList<String>> entry : map.entrySet()) {
            String key = entry.getKey();
            ArrayList<String> valueList = entry.getValue();
            System.out.println(key + " " + valueList);
        }
    

    【讨论】:

      【解决方案4】:
      for (String l : reports[i]) {
              String[] g = l.split("_");
              for (String r : pckg) {
                  if (g[0].equalsIgnoreCase(r)) {
                      report = dirFiles.get(g[0]);
                      if(report == null){ report = new ArrayList<String>(); } //create new report
                      report.add(g[1]);
                      dirFiles.put(g[0], report);
                  }
              }
      }
      
      • 删除了if 条件的else 部分。您正在使用 break 退出内部循环,并且您永远无法评估第一个键之外的键。
      • 增加了对现有值的检查。正如 Orin2005 所建议的那样。
      • 此外,我已将语句 String[] g = l.split("_"); 移到内部循环之外,这样它就不会被多次执行。

      【讨论】:

      • dirFiles.put(g[0], report); 行中,我认为您还需要考虑该密钥的HashMap 中已经存在的所有内容。所以应该是dirFiles.put(g[0], dirFiles.get(g[0]).addAll(report));什么的,这取决于report的值是什么。
      • 我假设报告是字符串列表,而 dirFiles 是具有键类型字符串和值类型字符串列表的 HashMap。在这种情况下,它会按预期工作。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-27
      • 2012-03-05
      • 2015-12-03
      • 1970-01-01
      • 2011-11-18
      • 2012-07-27
      • 1970-01-01
      相关资源
      最近更新 更多