简体   繁体   English

HashMap上的NullPointerException

[英]NullPointerException on HashMap

I have a HashMap<Integer, JButton> . 我有一个HashMap<Integer, JButton> The problem is when I try to retrieve a value I get null , not a JButton. 问题是当我尝试获取一个值时,我得到的是null ,而不是JButton。 The exception occurs when I try to add "butt" to centerPanel in the last line. 当我尝试在最后一行中将“对接”添加到centerPanel时,会发生异常。 Below is a snippet of my code an 2 class fields to put the code into perspective. 下面是我的代码片段和2个类字段,以将代码置于透视图中。

public class GUI {

private JPanel centerPanel;
private JButton button;
private JLabel label;
private Image source;
private Image image;
private HashMap<Integer, JButton> images = new HashMap<>();

public GUI() {

    centerPanel = new JPanel();

    ImageIcon sid = new ImageIcon(GUI.class.getResource("koala.jpg"));
    source = sid.getImage();


    int ind = 0;

    for ( int i = 0; i < 4; i++) {
        for ( int j = 0; j < 3; j++) {

            if ( j == 2 && i == 3) {
                label = new JLabel("");
                centerPanel.add(label);
            } else {
                button = new JButton();
                button.addActionListener(this);
                images.put(new Integer(++ind), button);
                image = createImage(new FilteredImageSource(source.getSource(),
                    new CropImageFilter(j*width/3, i*height/4, 
                        (width/3)+1, height/4)));
                button.setIcon(new ImageIcon(image));
            }
        }
    }

    Random random = new Random();

    for (int i=0; i<11; i++) {
        Integer numb = new Integer(random.nextInt(images.size()));
        JButton butt = images.get(1);
        centerPanel.add(butt);
        images.remove(numb);
    }

    setSize(1024, 768);
    setTitle("Puzzle");
    setResizable(false);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    setVisible(true);
}

public static void main(String[] args) {
    new GUI();
}  
}

Why does the NullPointerException occur? 为什么会发生NullPointerException? I'm aware I don't need to explicitly create Integers. 我知道我不需要显式创建Integer。

Here is a SSCCE 这是一个SSCCE

@Test
public void mapNPE() {

    Map<Integer, String> images = new HashMap<>();
    int ind = 0;
    for ( int i = 0; i < 4; i++) {
        for ( int j = 0; j < 3; j++) {
            if ( j == 2 && i == 3) {
                System.out.println("j == 2 && i == 3");
            } else {
                images.put(new Integer(++ind), Integer.toString(i) + "," + Integer.toString(j));
            }
        }
    }

    Random random = new Random();

    for (int i=0; i<11; i++) {
        Integer numb = new Integer(random.nextInt(images.size()));
        System.out.println(numb);
        if(numb == 1) {
            System.out.println("Image will be removed, next iteration will get null from map");
        }
        String butt = images.get(1);
        System.out.println(Integer.toString(i) + "=" + butt);
        images.remove(numb);
    }
}

and the output is 输出是

j == 2 && i == 3
4
0=0,0
3
1=0,0
3
2=0,0
8
3=0,0
5
4=0,0
1
Image will be removed, next iteration will get null from map
5=0,0
5
6=null
3
7=null
1
Image will be removed, next iteration will get null from map
8=null
4
9=null
5
10=null

I guess now you get why you randomly get a NPE 我想您现在知道为什么您会随机获得NPE

Integer numb = new Integer(random.nextInt(images.size()));
JButton butt = images.get(1);
centerPanel.add(butt);
images.remove(numb);

On one iteration numb will be equal to 1 (this can occur on any iteration, as you retrieve a random number between 0 and images.size(), and this is guaranteed to occur, since images.size() decreases from 11 to 1), so element under index 1 will be removed. 在一次迭代中, numb等于1(在任何迭代中都可能发生,因为您检索到0和images.size()之间的随机数,并且由于images.size()从11减少到1,因此可以保证会发生这种情况。 ),因此索引1下的元素将被删除。 On next iteration images.get(1) returns null . 在下一次迭代中, images.get(1)返回null Then you attempt centerPanel.add(butt); 然后尝试centerPanel.add(butt); and get an NPE. 并获得NPE。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM