导致 NullPointerException 的程序

Program causing NullPointerException

这是名为“Algorithm.java”的文件

package leetcode;

import java.util.HashMap;
import java.util.Map;

public class Algorithms {
    public static int romanToInteger(String roman) {
        Map<String, Integer> romanValues = new HashMap<>();

        romanValues.put("I", 1);
        romanValues.put("V", 5);
        romanValues.put("X", 10);
        romanValues.put("L", 50);
        romanValues.put("C", 100);
        romanValues.put("D", 500);
        romanValues.put("M", 1000);
        int integer = romanValues.get(Character.toString(roman.charAt(roman.length() - 1)));
        int previousValue = integer, current;

        for (int i = roman.length() - 2; i >= 0; i--) {

            current = romanValues.get(Character.toString(roman.charAt(i)));

            if (current < previousValue) {
                integer -= current;
            } else {
                integer += current;
            }

            previousValue = current;
        }
        return integer;
    }
}

这里是我调用代码的地方的“Main.java”

package leetcode;

public class Main {
    public static void main(String[] args) {
        System.out.println(Algorithms.romanToInteger("XII"));
    }
}

我是 Java 的新手,我不明白为什么这一行会导致 NullPointerException。

int integer = romanValues.get(roman.charAt(roman.length() - 1));

但是当我像这样将 romanValues.get() 参数转换为字符串时

int integer = romanValues.get(Character.toString(roman.charAt(roman.length() - 1)));

运行良好。

int integer = romanValues.get(roman.charAt(roman.length() - 1));

让我们回顾一下失败代码中的操作顺序:

  1. roman.charAt(roman.length() - 1) - returns roman 字符串的最后一个 char
  2. romanValues.get - 根据 Map javadoc an Objectis expected 在运行时 - 这里密钥的特定类型已经被删除 - 因此 char 值被装箱进入 Character,然而,由于地图是用 String 键定义的,因此 get returns null -- 找不到 Character关键。
  3. 赋值 int integer = null 导致拆箱(Integer 必须转换为原始 int)并且此尝试导致 NullPointerException 因为 nullget.
  4. 返回

因此,为了使上述代码与 Character 键一起使用,您还可以修复 romanValues 映射中的键类型,并可能使用 getOrDefault 为丢失的键:

Map<Character, Integer> romanValues = new HashMap<>();

romanValues.put('I', 1);
romanValues.put('V', 5);
romanValues.put('X', 10);
romanValues.put('L', 50);
romanValues.put('C', 100);
romanValues.put('D', 500);
romanValues.put('M', 1000);

int integer = romanValues.getOrDefault(roman.charAt(roman.length() - 1), 0);

Map.get : Map.get return returns null 如果指定的键为空且此映射不允许空键(可选))

String.charAt(roman.charAt) : return 字符

因此

romanValues(Map) 的键是字符串。 char和String的区别。

例如

//false
System.out.println("A".equals('A'));