有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么我在这个对象上得到一个NullPointerException?

我有一个类型为PolyaUrn的对象,名为myUrn。我实例化它并使用一些方法来操作它。然后,我得到名为ballCountsint[]字段。我将这个int[]传递给一个构造函数,以创建一个名为suSimpleUrn类型的新对象。然而,当我试图调用su上的方法时,我得到一个NullPointerException。我正在使用new关键字创建类型为SimpleUrn的对象,并指向变量su。我不明白为什么不能使用解引用操作符.引用su

代码如下:

import java.util.Arrays;

class PolyaUrnProg {

  public static void main(String[] args) {
    PolyaUrn myUrn = new PolyaUrn();
    myUrn.draw();
    myUrn.draw();
    System.out.println(myUrn);
    System.out.println();

    int numDraws = 100; // we will make another 98 draws from the urn

    for (int i = 0 ; i < numDraws-2 ; i++) {
      myUrn.draw();
    }
    System.out.println("...and after 98 more draws:\n");
    System.out.println(myUrn);

    System.out.println('\n');
    System.out.println("Let's construct a SimpleUrn from original PolyaUrn.");

    // initialising new int array with the same size as myUrn
    int[] a = new int[myUrn.getArray().length];

    // copying myUrn into 'a'
    a = Arrays.copyOf(myUrn.getArray(), myUrn.getArray().length);

    // passing 'a' to constructor in SimpleUrn to initialize it
    SimpleUrn su = new SimpleUrn(a);

    //ERROR - NullPointException
    su.toString();
  }
}

PolyaUrn类:

import java.util.Arrays;

class PolyaUrn {

  private int[] ballCounts;
  private int lastDraw;

  public PolyaUrn() { // Sets up PolyaUrn by rolling it

    ballCounts = new int[2]; // initially two possibilities
    ballCounts[0] = 1;
    ballCounts[1] = 1;

    // last draw is not a meaningful value until a ball is drawn.
    lastDraw = -1;
  }

  public int[] getArray() {
    return ballCounts;
  }

  public int getLastDraw() {
    return lastDraw;
  }

  public int[] updateUrn(int b) {

    if(b == 0) {

      int[] newUrn = Arrays.copyOf(ballCounts, ballCounts.length+1);
      newUrn[newUrn.length-1] = 1;
      ballCounts = newUrn;

    } else {

      ballCounts[b] = ballCounts[b]+1;
    }

    return ballCounts;
  }

  public void draw() {
    int ballDrawn = WeightedSampler.sample(ballCounts);
    updateUrn(ballDrawn);
    lastDraw = ballDrawn;
  }

  public String toString() {
    String s = "Polya Urn\n=========\n\n";
    s += "Ball-counts are as follows:\n\n";
    s += " Value\t| Count\n";
    s += "----------------\n";
    for (int ballValue = 0; ballValue < ballCounts.length ; ballValue++) {
      s += "  " + ballValue + "\t|  " + ballCounts[ballValue] + "\n";
    }
    return s;
  }
}

SimpleUrn类:

import java.util.Arrays;

class SimpleUrn {

  private int[] ballCounts;
  private int lastDraw;

  public SimpleUrn(int[] ballArray) { // Sets up PolyaUrn by rolling it

    int[] ballCounts = ballArray;

    // last draw is not a meaningful value until a ball is drawn.
    lastDraw = -1;
  }

  public int getLastDraw() {
    return lastDraw;
  }

  public int[] updateUrn(int b) {

    ballCounts[b] = ballCounts[b]-1;
    return ballCounts;
  }

  public void draw() {

    int ballDrawn = WeightedSampler.sample(ballCounts);
    updateUrn(ballDrawn);
    lastDraw = ballDrawn;
  }

  public String toString() {
    String s = "Polya Urn\n=========\n\n";
    s += "Ball-counts are as follows:\n\n";
    s += " Value\t| Count\n";
    s += "----------------\n";
    for (int ballValue = 0; ballValue < ballCounts.length ; ballValue++) {
      s += "  " + ballValue + "\t|  " + ballCounts[ballValue] + "\n";
    }
    return s;
  }
}

注意:这些类使用第三个类WeightedSampler,以防有人想要编译。这门课在这里:

import java.util.Random;
import java.util.stream.*;

public class WeightedSampler {

  private static Random generator = new Random(); 

  public static int sample(int[] weights) {
    int total = calculateSum(weights);
    int remains = generator.nextInt(total);
    int index = 0;

    while (index < weights.length) {
      remains -= weights[index];
      if (remains < 0) {
        break;
      }
      index++;
    }
    return index;
  }

  public static int calculateSum(int[] arr){
    return IntStream.of(arr).sum();
  }
}

共 (1) 个答案

  1. # 1 楼答案

    你在SimpleUrn构造函数中对ballCounts进行跟踪。改变这个

    public SimpleUrn(int[] ballArray) { // Sets up PolyaUrn by rolling it
        int[] ballCounts = ballArray;
    
        // last draw is not a meaningful value until a ball is drawn.
        lastDraw = -1;
    }
    

    public SimpleUrn(int[] ballArray) { // Sets up PolyaUrn by rolling it
        this.ballCounts = ballArray;
    
        // last draw is not a meaningful value until a ball is drawn.
        lastDraw = -1;
    }