0

Anyone knows what is wrong with my pointer (value)? Exception in thread "main" java.lang.NullPointerException My program:

import java.util.LinkedHashMap;

public class Solution {
    private static LinkedHashMap<String, Integer> romanToNum = new LinkedHashMap<String, Integer>(); 
    static{
        romanToNum.put("M", 1000);
        romanToNum.put("D", 500);
        romanToNum.put("C", 100);
        romanToNum.put("L", 50);
        romanToNum.put("X", 10);
        romanToNum.put("V", 5);
        romanToNum.put("I", 1);
    }
    public int romanToInt(String s) {
        int sum = 0;
        char prev = '#';
        for(int i = s.length()-1; i >= 0; i--){
            char ch = s.charAt(i);
            ***int value = romanToNum.get(ch);***
            if(value < sum && ch != prev){
                sum -= value;
            }else{
                sum += value;
            }
            prev = ch;
        }
        return sum;
    }
}
Barranka
  • 20,547
  • 13
  • 65
  • 83

4 Answers4

3

Your map is of type <String, Integer>, but you are using char primitives as the keys (for lookup):

char ch = s.charAt(i);
***int value = romanToNum.get(ch);***

These get autoboxed to Character objects, which are not compatible with Strings. Thus, as others have noted, your map returns a null Integer, which gets auto-unboxed to a primitive int, and it is this operation which causes NPE to be thrown.

Solution 1: Make the map of type <Character, Integer> instead.

Solution 2: Change the offending line to:

***int value = romanToNum.get(String.valueOf(ch));***
torquestomp
  • 3,304
  • 19
  • 26
  • Yeah, me too. Unusual to have two serious bugs on the same line of code. But wouldn't there have been a compile error from trying to look up a `char` in a map whose keys are `String`? – Dawood ibn Kareem Jul 07 '14 at 23:37
  • Nope! `Map.get()` takes `Object` as an argument, not `K`. This API decision unfortunately leads to runtime errors like the one found here, but it's also what lets you call `.get()` at all on a `Map extends K, ? extends V>`. Java Generics are fun. – torquestomp Jul 07 '14 at 23:43
  • Map was created in Java 2, before generics, so the signature was originally `Object get(Object key)`. It was changed to `V get(Object key)` once covariant returns were allowed in Java 5, but the parameter couldn't be changed to `K` without breaking backwards compatibility. – David Conrad Jul 07 '14 at 23:46
  • 1
    @DavidConrad Java 5 was also the release that introduced generics, so I believe they were in fact free to change the signature to `V get(K key)` without breaking 1.4 and below, because the default raw-types interpretation would just set treat these as ``. But, for other reasons, they chose to leave it as `Object`. Related: http://stackoverflow.com/questions/857420/what-are-the-reasons-why-map-getobject-key-is-not-fully-generic – torquestomp Jul 07 '14 at 23:51
1

import java.util.*;

public class Roman_to_Integer {

public String getRomanValue(String x) {
    String str[] = new String[12];
    str[0] = x.replaceAll("IIIII", "V");
    str[1] = str[0].replaceAll("IIII", "IV");
    str[2] = str[1].replaceAll("VV", "X");
    str[3] = str[2].replaceAll("VIV", "IX");
    str[4] = str[3].replaceAll("XXXXX", "L");
    str[5] = str[4].replaceAll("XXXX", "XL");
    str[6] = str[5].replaceAll("LL", "C");
    str[7] = str[6].replaceAll("LXL", "XC");
    str[8] = str[7].replaceAll("CCCCC", "D");
    str[9] = str[8].replaceAll("CCCC", "CD");
    str[10] = str[9].replaceAll("DD", "M");
    str[11] = str[10].replaceAll("DCD", "CM");

    return str[11];
}

public static void main(String args[]) {
    Scanner in = new Scanner(System.in);
    Roman_to_Integer obj = new Roman_to_Integer();
    String Temp = "";
    System.out.print("Enter The Number : ");
    int Num = in.nextInt();
    for(int i = 1 ; i <= Num ; i++) {
        Temp = Temp + "I";
    }

    String Roman = obj.getRomanValue(Temp);

    System.out.print("The Roman Value Of "+Num+" is "+Roman);
}

}

this is the most logical and simplest approach the method getRomanValue(String x) actually Coverts All the "III.... "to the Respective value. In The Main method I Have Collected n Numbers Of "I" The I Have Replaced the "I" with The Respective Value Such as "V" or "L" .

NOTE: The function/method getRomanValue(String x) is in ascending Order Of Value Which Is Very Important...

Saikat Das
  • 59
  • 11
0

The problem is that you are calling get using a char, which is auto boxed to a Character.

char ch = s.charAt(i);
int value = romanToNum.get(ch);

Since no data is actually stored with Character keys, a null is returned. As others have pointed out, the null Integer is auto unboxed to an int, resulting in a NullPointerException.

Brett Okken
  • 6,210
  • 1
  • 19
  • 25
0

As my map is , I used char as the key. Using string instead of char: String str = String.valueOf(ch);

NullPointerException usually has two methods: 1. none initialization 2. using a null to compare, figure, transfer.