Note: This is a troubling problem, possibly a bug, although I might be incorrect and missing something small
Problem:
Issue is the separately instantiated objects are referring to the same data structure.
Calling a.add() adds an object to data[NEXT], where is instantiated to NEXT = 0, followed by NEXT++ for increment purposes.
Thereafter, b.add() is called, and following the logic of the add() method, the array is extended,
BUT no initial value has been inserted into b i.e. b.data[0] = null
TL;DR
a.add() adds value to a.
b.add() extends a's array. This should not happen as a and b are 2 separate objects of the same type
main class code:
//...
SimpleSet<Integer> a = new SimpleSet<>();
SimpleSet<Integer> b = new SimpleSet<>();
// add a maximum of 20 unique random numbers from 0..99
Random rand = new Random();
for (int i = 0; i < 20; i++) {
a.add(rand.nextInt(100)); //i=0 - adds to data[0] with no issue
b.add(rand.nextInt(100)); //i=0 - extends a's array? why?
}
//...
class SimpleSet
public class SimpleSet<E> {
private static int MIN_SIZE = 1;
private static int NEXT = 0;
private Object[] data;
/**
* constructor of SimpleSet
*/
public SimpleSet() {
data = new Object[MIN_SIZE];
}
public void add(E e) {
if(NEXT > 0.75*MIN_SIZE){
extendArray();
}
if (data != null) {
data[NEXT] = e;
NEXT++;
}
}
private void extendArray() {
MIN_SIZE = MIN_SIZE*2;
Object[] newData = new Object[MIN_SIZE];
for (int i = 0; i < data.length; i++) {
newData[i] = data[i];
}
data = newData;
return;
}
//...
}
Am I missing something small or is this a bug?
IDE = IntelliJ 2016.3
Related
This question already has answers here:
java "void" and "non void" constructor
(5 answers)
Closed 5 years ago.
When ever I add an object to this ArrayList, my resize method, gives me a NullPointerException. The list is initialized with a size of 1, and the first element is added to possition 0 in the array.
Here is my arrayList AKA DynamicArray
//Implementation of a dynamic array
// Add remove methods
public class DynamicArray {
private Object[] data;
private int size;
public void DynamicArray(){
data = new Object[1];
size = 0;
}
public int size(){return size;}
public Object get(int index){return data[index];};
private void resizeIfFull()
{
if (size < data.length){
return;
} else {
Object[] bigger = new Object[2 * data.length];
for (int i = 0; i < data.length; i++){
bigger[i] = data[i];
data = bigger;
}
}
}
public void add(Object obj){
resizeIfFull();
data[size] = obj;
size++;
}
public void add(int index, Object obj){
resizeIfFull();
for(int i = size - 1; i >= index; i--){
data[i+1] = data[i];
}
data[index] = obj;
size++;
}
public void remove(int index){
for(int i = index; i < size; i++){
data[i] = data[i+1];
}
size--;
}
}
Here is my testing class.
public class AlgorTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
DynamicArray dynam = new DynamicArray();
System.out.println(dynam.size());
dynam.add("first");
}
}
Here is my output from the testing class.
0
Exception in thread "main" java.lang.NullPointerException
at DynamicArray.resizeIfFull(DynamicArray.java:20)
at DynamicArray.add(DynamicArray.java:38)
at AlgorTest.main(AlgorTest.java:8)
Confusingly, this isn't a constructor:
public void DynamicArray(){
data = new Object[1];
size = 0;
}
It's a function called DynamicArray (very confusing, I know).
Without the class having a constructor, data remains null and leads to an NPE when you try to access the array.
Drop the void keyword to turn the function into a constructor (which would then initialize data etc):
public DynamicArray(){
data = new Object[1];
size = 0;
}
constructor doesn't have return value , remove return type from constructor (void)
public DynamicArray(){
data = new Object[1];
size = 0;
}
in your case when you initialize object from DynamicArray class then default constructor will execute which does nothing
My apologize, I have a class on my Project, called test01.java. And i used the library from Tadaki Graphlib contained many class. On of them is Graph.java.
Test01.java:
public class test01 extends Graph{
public test01(String name, int n) {
super(name);
public test01(String name, int n) {
super(name);
graphLib.Vertex vList[] = new graphLib.Vertex[n];
for (int i = 0; i < n; i++) {
vList[i] = new graphLib.Vertex(String.valueOf(i));
addVertex(vList[i]);
}
int deg = 0;
System.out.println("<---------- Random val ---------->");
addArc(vList[0], vList[1], String.valueOf(0)); deg++;
addArc(vList[1], vList[0], String.valueOf(1)); deg++;
System.out.println("Vertex-0 with Vertex-1");
System.out.println("Vertex-1 with Vertex-0");
int k = 2;
int l;
int m=0;
Random randomval = new Random();
int isAvailInt [] = new int[n];
while (k<n) {
for(l=0;l<k;l++){
isAvailInt [l]= Integer.parseInt(vList[l].toString());
m=isAvailInt[l];
}
int chosen = randomval.nextInt(m);
addArc(vList[k], vList[chosen], String.valueOf(k));
System.out.println("Vertex-"+k+" with Vertex-"+chosen+
" exp = " + String.valueOf(k));
k++;
}
}public static void main(String args[]) {
int n;
String num = JOptionPane.showInputDialog("Masukkan nilai jumlah iterasi = ");
String degnum = null;
n = Integer.parseInt(num);
int deg []= new int [n];
test01 t = new test01("test",n);
System.out.println("<---------- Vertex-i = Degree-i ------------>");
graphLib.Graph g= new Graph("test");
int [][]adj = g.getAdjacent();
System.out.println(adj[0][0]);
for (int i=0; i<t.getSize();i++){
for (int j=0; j<t.getSize();j++){
}
}}
and one other class called Graph.java
public class Graph extends GraphBase { int adjacent[][] = null;
public Graph(String name) {
this.name = name;
vertexes = Utils.createVertexList();
arcs = Utils.createArcList();
a2vHead = new HashMap<>();
a2vTail = new HashMap<>();
v2a = new HashMap<>();
}
public int[][] getAdjacent() {
int n = vertexes.size();
adjacent = new int[n][];
for (int i = 0; i < n; i++) {
adjacent[i] = new int[n];
for (int j = 0; j < n; j++) {
adjacent[i][j] = 0;
}
}
if (directed) {
for (int i = 0; i < n; i++) {
Vertex v = vertexes.get(i);
for (Arc a : v2a.get(v)) {
Vertex t = a2vTail.get(a);
int l = vertexes.indexOf(t);
adjacent[l][i]++;
}
}
} else {
for (int i = 0; i < n; i++) {
Vertex v = vertexes.get(i);
for (Arc a : v2a.get(v)) {
Vertex t = a2vTail.get(a);
if (!t.equals(v)) {
int l = vertexes.indexOf(t);
adjacent[i][l]++;
adjacent[l][i]++;
}
}
}
}
checkConnectedness();
return adjacent;
}}
From above, method - int [][] Adjacent() - has an array return value:
return adjacent;
Then I want to received it with array variable declared:
int [][]adj = g.getAdjacent();
But when I run the program, the code :
System.out.println(adj[0][0]);
Has appeared error :
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
I've declare the variable vertexes in Graph.java that extended from other class, GraphBase.java:
vertexes = Utils.createVertexList();
How do I obtain an array value form a variable adjacent in Graph.java to test01.java and how do I display it with System.out.println() ?
Well you haven't shown where vertexes is initialized (or even declared) in Graph. I suspect it's empty, so when you execute this code:
public int[][] getAdjacent() {
int n = vertexes.size();
adjacent = new int[n][];
...
return adjacent;
}
... you'll end up with an empty array. That would cause the problem you've seen. You can easily check the size in your main method:
System.out.println(adj.length);
I suspect you'll find it's 0. Either that, or adj[0].length is 0.
It's not clear how you expect the Graph to find any vertexes - you don't supply it with any, or even the value of n. You just call the constructor with a string:
graphLib.Graph g= new Graph("test");
Unless that's meant to be the name of a file which is loaded in the constructor, there's nowhere for it to get data from. You need to take a step back and think about where you expect the data to come from, then make sure that it can actually flow through your program. The problem isn't getting the array reference back to main - the problem is that the array is empty.
I doubted about this line returning 0.
int n = vertexes.size();
You can reproduce this issue by running below code
int adjacent[][] = new int[0][];
System.out.println(adjacent[0][0]);
You will get the same exception
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
To solve this issue
Make sure before proceeding vertexes have expected values.
I got a null pointer exception when accessing a static array from a static member method.
The exception is thrown when i call setData(x, y, z) from a thread. When I debugged it I found out data[0] is null when i try to write to it. I just don't understand how it can be null
public class dataContainer
{
private static final short nrOfDataElements = ids.total_ids;
private static regularDataElement[] data = new regularDataElement[nrOfDataElements];
public static synchronized void getData(final short i, regularDataElement r)
{
if ( (i >= 0) && (i < nrOfDataElements) )
r.set(data[i].getTimestamp(), data[i].getValue());
}
public static synchronized void setData(short i, double ts, long val)
{
if ( (i >= 0) && (i < nrOfDataElements) )
data[i].set(ts, val); //<<-------null pointer exception, debugging showed data[i] == null, (with i = 0 and nrOfDataElements = 12)
}
}
and
public class regularDataElement
{
regularDataElement()
{
set(0, 0);
}
public void set(double _ts, long _val)
{
System.out.println(this.ts + " " + _ts + " " + this.val + " " + _val); System.out.flush();
this.ts = _ts;
this.val = _val;
}
public double getTimestamp()
{
return this.ts;
}
public long getValue()
{
return this.val;
}
private double ts;
private long val;
}
The statement private static regularDataElement[] data = new regularDataElement[nrOfDataElements]; initializes data with an array the size of nrOfDataElements. It does not initialize each element in this array. I.e., all the elements are null.
If you wish to initialize the elements, you should do so yourself. E.g., you could add a static block to handle this:
static regularDataElement[] data = new regularDataElement[nrOfDataElements];
static {
for (int i = 0; i < nrOfDataElements; ++i) {
data[i] = new regularDataElement();
}
}
Did you ever initialize the data array?
private static regularDataElement[] data =
new regularDataElement[nrOfDataElements];
will create an array full of null objects of size nrOfDataElements. It won't actually initialize any elements in the array.
You don't appear to be allocating memory for data[i], which is why you're getting the NPE.
Allocating memory for the array itself is not enough. You need to allocate memory for each element:
for (int i = 0; i < nrOfDataElements; ++i) {
data[i] = new regularDataElement(...);
}
(Replace ... with the actual arguments.)
You never actually create any objects. You must add somewhere:
for (int i = 0; i < data.length; i++) {
data[i] = new regularDataElement();
}
When you initialize an Object array in Java, like data in your code, all elements are by default set to null.
So, you need to populate the data array first, before being able to call any methods against its elements.
Assuming that the regularDataElement class has a no-args (i.e., no parameters) constructor, you could do
static regularDataElement[] data = new regularDataElement[nrOfDataElements];
static
{
for (int i=0; i<nrOfDataElements; i++)
{
data[i] = new regularDataElement();
}
}
Of course, you could have a separate method to initialize the array, e.g.
static regularDataElement[] initialize(int nrOfDataElements)
{
regularDataElement[] elements = new regularDataElement[nrOfDataElements];
for (int i=0; i<nrOfDataElements; i++)
{
elements[i] = new regularDataElement();
}
return elements;
}
and then call that method to create and initialize the data array, replacing the statement
static regularDataElement[] data = new regularDataElement[nrOfDataElements];
with
static regularDataElement[] data = initialize(nrOfDataElements);
Also, as a matter of following established coding conventions, you should name your classes starting with a capital letter, i.e. use RegularDataElement instead of regularDataElement.
I've been searching a lot for this problem and I can't find a solution. I'm trying to build a mini-game and I have a method for creating platforms. I have a class with every platform parameters, and I made a class array so i can have multiple platforms at the same time.
Problem: When I try to call the method for constructing the platform by sending the parameters I want, it gives me a NullPointerException. The method was working before, but with everything static and so i couldnt have multiple instances of that class, and now I removed the static fields from the platform class and it gives me the NullPointerException every time I call the method.
I copied the part of the code that gives me the error, the error goes the following way:
public static void main(String[] args) {
Game ex = new Game();
new Thread(ex).start();
}
In Game class:
public Load_Stage load = new Load_Stage();
public Game() {
-other variables initializatin-
Initialize_Items();
load.Stage_1(); // <--- problem this way
In Load_Stage class:
public class Load_Stage {
public Platforms plat = new Platforms();
public void Stage_1(){
Stage_Builder.Build_Platform(200, 500, 300, plat.platform1);
Stage_Builder.Build_Platform(100, 200, 100, plat.platform1);
}
}
And inside the Stage_Builder class:
public class Stage_Builder {
public static final int max_platforms = 10;
public static Platform_1[] p1 = new Platform_1[max_platforms];
public static boolean[] platform_on = new boolean[max_platforms];
public Stage_Builder() {
for (int c = 0; c < platform_on.length; c++) {
platform_on[c] = false;
}
}
public static void Build_Platform(int x, int y, int width, ImageIcon[] type) { // BUILDS A PLATFORM
for (int b = 0; b < max_platforms; b++) {
if (platform_on[b] == false) {
p1[b].Construct(x, y, width, type); // <-- NullPointerException here
platform_on[b] = true;
break;
}
}
}
}
Thanks beforehand.
EDIT: Here's the Platform_1 class (sorry for forgetting about it):
public class Platform_1 {
private int platform_begin_width = 30;
private int platform_middle_width = 20;
public int blocks_number = 0;
public ImageIcon[] platform_floors = new ImageIcon[500];
private int current_width = 0;
public int [] platform_x = new int [500];
public int platform_y = 0;
public int platform_width = 0;
public void Construct(int x, int y, int width, ImageIcon [] type) {
platform_width = width;
platform_y = y;
for (int c = 0; current_width <= platform_width; c++) {
if (c == 0) {
platform_x[c] = x;
platform_floors[c] = type[0];
current_width += platform_begin_width;
} else if ((current_width + platform_middle_width) > platform_width) {
platform_floors[c] = type[2];
blocks_number = c + 1;
platform_x[c] = current_width + x;
current_width += platform_middle_width;
} else {
platform_floors[c] = type[1];
platform_x[c] = current_width + x;
current_width += platform_middle_width;
}
}
}
}
And the Platforms class:
public class Platforms {
public ImageIcon[] platform1 = {new ImageIcon("Resources/Sprites/Stage_Objects/Platform1/begin.png"),
new ImageIcon("Resources/Sprites/Stage_Objects/Platform1/middle.png"),
new ImageIcon("Resources/Sprites/Stage_Objects/Platform1/end.png")};
}
The problem and solution are both obvious.
public static Platform_1[] p1 = new Platform_1[max_platforms];
After this line of code executes, p1 is an array of references of type Platform_1 that are all null.
Executing this line of code tells you so right away:
p1[b].Construct(x, y, width, type); // <-- NullPointerException here
The solution is to intialize the p1 array to point to non-null instances of Platform_1.
Something like this would work:
for (int i = 0; < p1.length; ++i) {
p1[i] = new Platform1();
}
I'm not seeing where you put things in the p1 array in the Stage_Builder class.
Another possibility (unlikely, but possible if you haven't shown everything) is that something in the Platform class, which you didn't show, is not initialized, and is breaking when you call Construct.
Also, the following seems problematic
public static Platform_1[] p1 = new Platform_1[max_platforms];
public static boolean[] platform_on = new boolean[max_platforms];
public Stage_Builder() {
for (int c = 0; c < platform_on.length; c++) {
platform_on[c] = false;
}
}
it appears you declare static variables p1 and platform_on, but you only populate platform_on in a constructor. So the first time you create a Stage_Builder instance, you populate one static array with all false, and don't put anything in the other static array...
Populate those static variables in a static block
// static var declarations
static {
// populate static arrays here.
}
The array you are calling a message on was never filled.
You have
public static Platform_1[] p1 = new Platform_1[max_platforms];
so p1 is
p1[0] = null
p1[1] = null
.
.
.
p1[max_platforms] = null
You try to call
p1[b].Construct(x, y, width, type);
which is
null.Construct(...);
You need to initialize that index on the array first.
p1[b] = new Platform_1();
p1[b].Construct(...);
First of all, your problem is that p1[b] is most likely null, as duffymo pointed out.
Secondly, you are using arrays in a really weird way. What about
a) delete Stage_Builder
b) Instead, have an ArrayList somewhere
c) The equivalent of Build_Platform1() look like this, then:
p1.add(new Platform1(x, y, width, type);
d) no if on[i], no max_platforms, no for loop to add a platform (the latter is a bad performance problem if you actually have a few hundret platforms)
Im working on this code and expecting a matrix to be printed but thats what came up
Matrix#2c78bc3b Matrix#2a8ddc4c
This is a code example:
public class Matrix
{
public static int rows;
public static int colms;//columns
public static int[][] numbers;
public Matrix(int[][] numbers)
{
numbers = new int[rows][colms];
}
public static boolean isSquareMatrix(Matrix m)
{
//rows = numbers.length;
//colms = numbers[0].length;
if(rows == colms)
return true;
else
return false;
}
public static Matrix getTranspose(Matrix trans)
{
trans = new Matrix(numbers);
for(int i =0; i < rows; i++)
{
for(int j = 0; j < colms; j++)
{
trans.numbers[i][j] = numbers[j][i];
}
}
return trans;
}
public static void main(String[] args)
{
int[][] m1 = new int[][]{{1,4}, {5,3}};
Matrix Mat = new Matrix(m1);
System.out.print(Mat);
System.out.print(getTranspose(Mat));
}
}
You need to implement toString() in a meaningful way.
This toString() (below) is perhaps suitable for debugging, but will be ugly and confusing if you use it for real user output. An actual solution would probably use a Formatter in some complicated way to produce neatly tabular rows and columns.
Some additional recommendations based on your code:
Suggest not storing the rows/columns sizes separately. SSOT / Single Source of Truth or DRY, Java+DRY. Just use the .length, and provide accessor methods if need be.
Use final in method args, it will eliminate bugs like you have above, aliasing numbers incorrectly int the constructor
Use an instance, not static
Paranoia is the programmer's lifestyle: I also modified my code to do a deepCopy of the provided int[][] array, otherwise there is reference leakage, and the Matrix class would be unable to enforce its own invariants if caller code later modified the int[][] they passed in.
I made my Matrix immutable (see final private numbers[][]) out of habit. This is a good practice, unless you come up with a good reason for a mutable implementation (wouldn't be surprising for performance reasons in matrices).
Here's some improved code:
public final class Matrix
{
final private int[][] numbers;
// note the final, which would find a bug in your cited code above...
public Matrix(final int[][] numbers)
{
// by enforcing these assumptions / invariants here, you don't need to deal
// with checking them in other parts of the code. This is long enough that you might
// factor it out into a private void sanityCheck() method, which could be
// applied elsewhere when there are non-trivial mutations of the internal state
if (numbers == null || numbers.length == 0)
throw new NullPointerException("Matrix can't have null contents or zero rows");
final int columns = numbers[0].length;
if (columns == 0)
throw new IllegalArgumentException("Matrix can't have zero columns");
for (int i =1; i < numbers.length; i++) {
if (numbers[i] == null)
throw new NullPointerException("Matrix can't have null row "+i);
if (numbers[i].length != columns)
throw new IllegalArgumentException("Matrix can't have differing row lengths!");
}
this.numbers = deepCopy(numbers);
}
public boolean isSquareMatrix() { return rowCount() == columnCount(); }
public int rowCount() { return numbers.length; }
public int columnCount() {return numbers[0].length; }
private static int[][] deepCopy(final int[][] source)
{
// note we ignore error cases that don't apply because of
// invariants in the constructor:
assert(source != null); assert(source.length != 0);
assert(source[0] != null); assert(source[0].length != 0);
int[][] target = new int[source.length][source[0].length];
for (int i = 0; i < source.length; i++)
target[i] = Arrays.copyOf(source[i],source[i].length);
return target;
}
public Matrix getTranspose()
{
int[][] trans = new int[columnCount()][rowCount()];
for (int i = 0; i < rowCount(); i++)
for (int j = 0; j < columnCount(); j++)
trans[i][j] = getValue(j, i);
return new Matrix(trans);
}
#Override
public String toString()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < numbers.length; i++)
{
for (int j = 0; j < numbers[i].length; j++)
sb.append(' ').append(numbers[i][j]);
sb.append('\n');
}
return sb.toString();
}
public static void main(String[] args)
{
final int[][] m1 = new int[][] { { 1, 4 }, { 5, 3 } };
Matrix mat = new Matrix(m1);
System.out.print(mat);
System.out.print(mat.getTranspose());
}
}
for a quick and dirty method:
public String toString() {
return Arrays.deepToString(numbers);
}
On an unrelated note, the variables rows, colms, numbers and the methods isSquareMatrix should not be declared as static. Otherwise, when you get a transpose, you're going to end up with two matrix objects writing to the same class variables.
You didn't define a toString method for your Matrix class, so when you try to print a Matrix you see the result of the default toString method which prints the object's class and unique id.
System.out.print(Mat);
it will call the toString method of the Matrix class.
So, if you want to print your Matrix, you will have to override toString method
#Override
public String toString() {
// create here a String representation of your matrix
// ie: String myString = "1 0 0 1\n0 1 1 1\n...";
return "String representation of my matrix";
}
To display the Matrix class object when you can print on it you'll have to define the toString method in your class.
Another bug in the code it you are not setting the value of rows and colms. So when you do
numbers = new int[rows][colms];
in your constructor, rows and colms will always have their default value of 0. You need to fix that. And then you'll have to copy the matrix elements from the parameter array to numbers.