【问题标题】:Putting array items into hashmap with 2 string使用 2 个字符串将数组项放入哈希图中
【发布时间】:2017-04-15 19:42:32
【问题描述】:

说,我有一个类似这样的数组,

{"A", "1", "B", "2", "C", "3"}

我想把它放到HashMap 像对一样,我尝试了几种方法,但似乎都没有。 我创建了一个方法 isDigit() 来检查项目是否为数字,

private static boolean isDigit(String str){
    try {
        Integer.parseInt(str);
    }
    catch (NumberFormatException nfe){
        return false;
    }
    return true;
}

然后我尝试分成 2 个数组,数字和字母。

for (int i = 0; i <= parts.length; i++) {
    if (isDigit(parts[i])) {
        numbers[i] = parts[i];
    } else {
        abcs[i] = parts[i];
    }
}

最后,

for (int i = 0; i < numbers.length ; i++) {
    map.put(abcs[i], numbers[i]);
}

然后我打印出来,

for (String each: map.keySet()) {
   System.out.println(each + ":" + map.get(each));
}

打印类似的东西,

1
A : null
2
B : null

它应该打印的是什么,

A : 1
B : 2
C : 3

【问题讨论】:

  • "A"1"B"2"C"3" 不是数组。
  • isDigit("10") 将返回 true,但 10 不是数字。 isInteger 会是一个更好的名字。
  • 你让它变得比必要的更难(和更慢)。为什么不直接遍历原始数组,将当前元素和下一个元素添加到地图中,然后将 2 添加到循环计数器? for (int i = 0; i &lt; array.length; i += 2) { map.put(array[i], array[i + 1]); }
  • @JB Nizet 已经尝试过了,让我也用它来编辑问题。
  • 有多种方法可以做到这一点,你的方法就是其中之一,尽管它不是最好的。仍然作为一种学习,您必须尝试了解代码中的错误或问题。我已经添加了我的答案,并试图用解决问题的解决方案来解释问题。希望它会有所帮助。 stackoverflow.com/a/43430604/504133

标签: java arrays hashmap


【解决方案1】:

为什么不通过增加2s 中的循环计数器来成对地遍历parts

for (int i = 0; i < parts.length -1; i += 2) {
    map.put(parts[i], parts[i + 1]);
}

【讨论】:

  • 已经试过了,如果我愿意,说map.get("A");,打印2 \n B
  • 我不认为你会想要这样做,因为你必须开始跟踪两个不常见的迭代。虽然此选项可能有效,但它不会通过代码审查。
  • 您需要发布创建数组的代码。这听起来像问题。 "2 \n B" 必须在数组中才能发生。
  • @GlenPierce IndexOutOfBoundsException 你的意思是。我现在用-1 解决了这个问题
  • @GlenPierce 哈哈:D
【解决方案2】:

问题在于你的 for 循环:

for (int i = 0; i <= parts.length; i++) {
    if (isDigit(parts[i])) {
        numbers[i] = parts[i];
    } else {
        abcs[i] = parts[i];
    }
}

您正在从 0 迭代到 5,所以您将 valies 放入偏移 1 的索引中。它是这样的:abcs[0] -> numbers[1] -> abcs[2] -

【讨论】:

  • 同意。在这里使用列表会更好。
【解决方案3】:

您对数组的迭代不均匀。

for (int i = 0; i <= parts.length; i++) {
    if (isDigit(parts[i])) {
        numbers[i] = parts[i];
    } else {
        abcs[i] = parts[i];
    }
}

假设 isDigit() 正常运行,您正在创建两个数组,但在创建它们时它们并没有按顺序排列。

所以当 i == 0 时,isDigit(parts[0]) 为 false,所以你创建 abcs[0] = parts[0],但是你在 abcs 中创建的下一个项目不是 abcs[1],而是abcs[2] 因为当它是一个数字时你跳过了 1。

【讨论】:

    【解决方案4】:

    在您的案例中存在索引问题。虽然查看输入类型还有其他方法 (One such way is mentioned in an another answer) 可以做到这一点,但我正在编辑您的代码,以便它可以按您的预期工作。

    int inputLength = parts.length; // assuming it is always even as it contains a pair (alphabet, number)
    int[] numbers = new int[inputLength/2];
    char[] abcs = new char[inputLength/2;
    
    int keyIndex = 0;
    int valueIndex = 0;
    
    for (int i = 0; i <= parts.length; i++) {
        if (isDigit(parts[i])) {
            numbers[keyIndex] = parts[i];
            keyIndex++;
        } else {
            abcs[valueIndex] = parts[i];
            valueIndex++;
        }
    }
    

    【讨论】:

      【解决方案5】:

      正如答案之一Your iterating over the array unevenly 中提到的那样,问题在于循环中的索引。 但我还想指出,您在方法isDigit(String str) 中以错误的方式使用异常处理 对控制流使用异常处理被认为是一种不好的做法。关于这个主题的问题的一个很好的答案在这里:Exceptions as control flow 我会将您的方法重构为这样的:

      private static boolean isDigit(String str){
          if (Character.isDigit(str.charAt(0))) { //assuming that the length of str is always 1
              return true;
          }
          return false;
      }
      

      希望这会有所帮助。

      【讨论】:

      • 字符串的长度并不总是1。
      • 好的,那么你可以使用正则表达式。 isDigit 方法体中的类似内容:return str.matches("[-+]?\\d*\\.?\\d+"); 它会将“120”或“0012”或“00.45”等字符串视为有效数字。可能您会根据您的具体需求调整正则表达式。无论如何,我的主要想法是告诉您,作为控制流的异常处理是一种反模式。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-19
      相关资源
      最近更新 更多