У меня есть объект типа PolyaUrn
с именем myUrn
. Я создаю его экземпляр и использую некоторые методы для манипулирования им. Затем я получаю int[]
поле myUrn
с именем ballCounts
. Я передаю это int[]
конструктору для создания нового объекта типа SimpleUrn
с именем su
. Однако, когда я пытаюсь вызвать методы на 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();
}
}