我运行测试时无法弄清楚NullPointerException

时间:2016-08-03 18:36:06

标签: java collections nullpointerexception

我一直得到一个空指针异常,我似乎无法找出原因。我正在运行一些测试,那就是当我得到空指针异常时,然而,当我从Pangrams main()运行它时,我没有遇到任何问题。我在下面列出了代码,测试和堆栈跟踪。任何帮助将不胜感激,并提前感谢!

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

public class Pangrams {
    private static TreeMap<Character, Integer> letterCount;

    public static void main(String[] args) {
        Pangrams pan = new Pangrams();
        System.out.println(pan.isPangram("the quick brown fox jumps over the lazy dog"));
        pan.getLetterCount();
    }

    public Pangrams() {
        letterCount = new TreeMap<>();
        populateMap();
    }

    public static boolean isPangram(String text) {

        if(text.length() < 26) return false;

        addToMap(text);

        for(Map.Entry<Character, Integer> entry : letterCount.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
            if(!(entry.getValue() >= 1)) {
                return false;
            }
        }

        return true;
    }

    public static void populateMap() {
        for(char x = 'a'; x <= 'z'; x++) {
            letterCount.put(Character.valueOf(x), 0);
        }
    }

    public static void addToMap(String text) {
        char[] textArray = text.toLowerCase().replace(" ", "").toCharArray();
        // System.out.println(textArray.length);

        for(char letter : textArray) {
            if(letterCount.containsKey(letter)) {
                int count = letterCount.get(letter);

                letterCount.put(letter, ++count);
                System.out.println(letterCount.get(letter));
            }
            else if(!Character.isWhitespace(letter)) {
                letterCount.put(letter, 1);
            }
        }
    }

    public static void getLetterCount() {
        for(Map.Entry<Character, Integer> entry : letterCount.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}

以下是测试:

import org.junit.Test;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;

public class PangramTest {

    @Test
    public void emptySentence() {
        assertFalse(Pangrams.isPangram(""));
    }

    @Test
    public void testLowercasePangram() {
        assertTrue(Pangrams.isPangram("the quick brown fox jumps over the lazy dog"));
    }

    @Test
    public void missingCharacterX() {
        assertFalse(Pangrams.isPangram("a quick movement of the enemy will jeopardize five gunboats"));
    }

    @Test
    public void mixedCaseAndPunctuation() {
        assertTrue(Pangrams.isPangram("\"Five quacking Zephyrs jolt my wax bed.\""));
    }

    @Test
    public void nonAsciiCharacters() {
        assertTrue(Pangrams.isPangram("Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich."));
    }

}

这是完整的堆栈跟踪:

java.lang.NullPointerException
    at Pangrams.addToMap(Pangrams.java:47)
    at Pangrams.isPangram(Pangrams.java:24)
    at PangramTest.testLowercasePangram(PangramTest.java:15)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:253)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

1 个答案:

答案 0 :(得分:-1)

好吧也许我没有在这个答案上清楚地解释自己。 你做错的事是在你的班级上调用静态方法。 调用静态方法不会实例化构造函数,即初始化地图的位置。

所以NULL指针异常正在抛出,因为你正在访问一个从未实例化过的地图。

进一步观察我不认为你需要你的地图在这个上下文中是静态的,所以下面的代码将地图保存在对象的状态中并重构你的测试用例以使用对象状态来调用你的方法,因为你的方法不是更长的静态,它们与你的对象状态联系在一起。

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

public class Pangrams
{
    private final TreeMap<Character, Integer> letterCount;

    public static void main(String[] args)
    {
        Pangrams pan = new Pangrams();
        System.out.println(pan.isPangram("the quick brown fox jumps over the lazy dog"));
        pan.getLetterCount();
    }

    public Pangrams()
    {
        letterCount = new TreeMap<Character, Integer>();
        populateMap();
    }

    public boolean isPangram(String text)
    {

        if(text.length() < 26)
        {
            return false;
        }

        addToMap(text);

        for(Map.Entry<Character, Integer> entry : letterCount.entrySet())
        {
            System.out.println(entry.getKey() + ": " + entry.getValue());
            if(!(entry.getValue() >= 1))
            {
                return false;
            }
        }

        return true;
    }

    public void populateMap()
    {
        for(char x = 'a'; x <= 'z'; x++)
        {
            letterCount.put(Character.valueOf(x), 0);
        }
    }

    public void addToMap(String text)
    {
        char[] textArray = text.toLowerCase().replace(" ", "").toCharArray();
        // System.out.println(textArray.length);

        for(char letter : textArray)
        {
            if(letterCount.containsKey(letter))
            {
                int count = letterCount.get(letter);

                letterCount.put(letter, ++count);
                System.out.println(letterCount.get(letter));
            }
            else if(!Character.isWhitespace(letter))
            {
                letterCount.put(letter, 1);
            }
        }
    }

    public void getLetterCount()
    {
        for(Map.Entry<Character, Integer> entry : letterCount.entrySet())
        {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}

测试:

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.Test;

public class PangramTest
{
    Pangrams pan = new Pangrams();

    @Test
    public void emptySentence()
    {
        assertFalse(pan.isPangram(""));
    }

    @Test
    public void testLowercasePangram()
    {
        assertTrue(pan.isPangram("the quick brown fox jumps over the lazy dog"));
    }

    @Test
    public void missingCharacterX()
    {
        assertFalse(pan.isPangram("a quick movement of the enemy will jeopardize five gunboats"));
    }

    @Test
    public void mixedCaseAndPunctuation()
    {
        assertTrue(pan.isPangram("\"Five quacking Zephyrs jolt my wax bed.\""));
    }

    @Test
    public void nonAsciiCharacters()
    {
        assertTrue(pan.isPangram("Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich."));
    }

}