Исключение нулевого указателя в TreeMap

Я попытался реализовать простую древовидную карту для подсчета вхождений целых чисел, но она дает мне NullPointerException, и я не знаю, как это исправить.

Exception in thread "main" java.lang.NullPointerException
    at exercises.CountOccurances_20_07.main(CountOccurances_20_07.java:21)

Вот код:

import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class CountOccurances_20_07 
{
    public static void main(String[] args) 
    {
        int[] list = {2, 3, 40, 3, 5, 4, 3, 3, 3, 2, 0};
        Map<Integer, Integer> map = new TreeMap<Integer, Integer>();
        for(int i: list)
        {
            int key = list[i];
            if(list.length > 1)
            {
                if(map.get(key) == 0)
                {
                    map.put(key, 1);
                }
                else
                {
                    int value = map.get(key).intValue(); // line 21
                    value ++;
                    map.put(key, value);
                }
            }
        }
        //get all entries into set
        Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet();
        //get key and value from entry set
        for(Map.Entry<Integer, Integer> entry: entrySet)
            System.out.println(entry.getValue() + "\t" + entry.getKey());
    }
}

person Doesn't Matter    schedule 30.08.2012    source источник


Ответы (4)


В вашем случае map.get(key) возвращает null и никогда не будет 0. Также вы используете ключ для поиска самого себя, что звучит неправильно.

for(int key: list) {
    Integer count = map.get(key);
    if (count == null) count = 0;
    map.put(key, count+1);
}
person Peter Lawrey    schedule 30.08.2012
comment
@Does'tMatter Мне нравится, чтобы все было просто. ;) - person Peter Lawrey; 30.08.2012

NullPointerException в строке 21

int value = map.get(key).intValue(); // line 21

это связано с тем, что map.get(key) вернет null, если key отсутствует на карте.

Вы должны использовать

if(!map.containsKey(key)){
}

вместо

if(map.get(key) == 0) {
}

так как он оценивает

if(null == 0){
}

и ваше условие ложно и тогда управление переходит на строку 21.

person Bharat Sinha    schedule 30.08.2012

сдача

map.get(key) == 0 

to

map.get(key) == null  

or

!map.contains(key)
person Ilya    schedule 30.08.2012

В вашем коде много очевидных недостатков.

Map создается на месте как пустая карта, но немедленно запрашивается, и результат get распаковывается:

Map<Integer, Integer> map = new TreeMap<Integer, Integer>();
...
if(map.get(key) == 0)

get возвращает null для несуществующей записи карты, а не ноль, и распаковка завершится ошибкой для нулевого аргумента.


Здесь list инициализируется на месте, но затем проверяется длина:

int[] list = {2, 3, 40, 3, 5, 4, 3, 3, 3, 2, 0};
if(list.length > 1)

Это лишняя проверка, удалите ее.


for(int i: list)
{
  int key = list[i];

То, как вы используете int i, скорее всего, неверно. расширенный цикл for присваивает каждому элементу массива по очереди значение i, так что, по всей вероятности, вы должны получить только for (int key : list).


int value = map.get(key).intValue(); // line 21

Вызов intValue излишен — об этом позаботится автоматическая распаковка. Вам нужно убедиться, что значение не равно нулю, прежде чем пытаться распаковать.

person Marko Topolnik    schedule 30.08.2012