0

Here's file named "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;
    }
}

and here's "Main.java" from where I am calling the code

package leetcode;

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

I am new to Java and I don't understand why this line is causing a NullPointerException.

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

But when I convert romanValues.get() argument to String like this

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

it runs fine.

Ritesh
  • 45
  • 6
  • Does this answer your question? [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – daniu Jul 24 '21 at 15:04

2 Answers2

0

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

Let's review the sequence of operations in the failing code:

  1. roman.charAt(roman.length() - 1) - returns the last char of roman string
  2. romanValues.get - according to Map javadoc an Objectis expected in runtime -- here the specific type of the key is already erased -- therefore the char value is boxed into Character, however, as the map is defined with String key, the get returns null -- nothing is found for a Character key.
  3. Assignment int integer = null causes un-boxing (an Integer has to be converted to primitive int) and this attempt causes NullPointerException because null is returned by get.

So in order for the mentioned code to work with Character key, you could also fix the type of keys in romanValues map and possibly use getOrDefault to provide default value for the missing keys:

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);
Nowhere Man
  • 19,170
  • 9
  • 17
  • 42
  • This makes sense. Can you explain the 3rd point further? I mean to ask if null is wrapped around by Integer object? – Ritesh Jul 24 '21 at 15:55
0

Map.get : Map.get return returns null if the specified key is null and this mapdoes not permit null keys(optional))

String.charAt(roman.charAt) : return char

Therefore

key of romanValues(Map<String, Integer>) is String. It is difference between char and String.

for example

//false
System.out.println("A".equals('A'));
bittap
  • 518
  • 1
  • 6
  • 15
  • What do you mean by "Map.get return returns null if the specified key is null and this mapdoes not permit null keys(optional)"? Could you please explain it further? – Ritesh Jul 24 '21 at 15:40
  • It is written in javadoc. NullPointerException - if the specified key is null and this mapdoes not permit null keys(optional) Therefore if map doesn't have key, It return null.Try to execute this ex) System.out.println(romanValues..get(Character.valueOf('A'))); – bittap Jul 24 '21 at 16:26