When I try to reset a list Marked I get a Null Pointer Exception.
The problem must be cause I never said what B and C is. (Boolean B, Integer C) And I don't know how to do this.
Here is a part of my code :
Marked[] marked;
//Create list marked!
public class Marked<B,C>{
public B bool;
public C comp;
}
public Graph(int N)
{
//Fill marked with false and 0
marked = new Marked[N];
for(int i=0;i<N;i++){
marked[i].bool = false;
marked[i].comp=0;
}
Creating an array of Marked doesn't actually initialize the elements in the array:
marked = new Marked[N];
for(int i = 0; i < N; i++) {
marked[i] = new Marked<Boolean, Integer>();
marked[i].bool = false;
marked[i].comp = 0;
}
The statement marked = new Marked[N]; creates a new array of Marked objects with N elements, but does not initialize them. Each element in this array would be null.
You need to manually initialize them by calling the constructor.
So, your for loop should look like this:
for(int i=0;i<N;i++) {
marked[i] = new Marked();
marked[i].bool = false;
marked[i].comp=0;
}
Related
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
I'm creating an ArrayList of type B:
ArrayList<B> cert= new ArrayList<B>;
B a = util.getCerts(path).iterator().next();
this.cert.add(a);
this.certNode(certs);
I'm getting a null pointer exception when I try to set the value:
void certNode(ArrayList<B> certResp)
{
ArrayList<RespNode> exp = new ArrayList<RespNode>();
for (int i = 0; i< certResp.size(); i++) {
exp.get(i).setxxx(certResp.get(i).getxxx());
exp.get(i).setxxx(certResp.get(i).getxxx().toString());
}
}
Any help would be great!
Since you just created the ArrayList instance exp, exp.get(i) doesn't exist, so you can't call exp.get(i).setxxx(...).
EDIT :
Try :
void certNode(ArrayList<B> certResp) {
ArrayList<RespNode> exp = new ArrayList<RespNode>();
for (int i = 0; i< certResp.size(); i++) {
exp.add(certResp.get(i).getxxx());
}
}
It's hard to be sure without knowing the return value of certResp.get(i).getxxx(), but if it returns RespNode, the code above would add that RespNode instance of the list.
The problem is here : exp.get(i). exp is the newly created ArayList, so it's empty, so there is a null at index i
Your list 'exp' is empty. In the for-loop you get a value of null; calling a method from null will cause the NullPointerException.
You have to put values in the list before you try to access them.
void certNode(ArrayList<B> certResp) {
ArrayList<RespNode> exp = new ArrayList<RespNode>();
for (int i = 0; i< certResp.size(); i++) {
exp.add(new RespNode()); // <-----
exp.get(i).setxxx(certResp.get(i).getxxx());
exp.get(i).setxxx(certResp.get(i).getxxx().toString());
}
}
btw you can improve syntax
void certNode(ArrayList<B> certResp) {
ArrayList<RespNode> exp = new ArrayList<RespNode>();
for (B b : certResp){
RespNode resp = new RespNode();
resp.setxxxx(b.getxxxx());
exp.add(resp);
}
}
As you are creating new empty ArrayList i.e []
exp.get(i)
gives you null
Instead you can use add method of ArrayList
void certNode(ArrayList<B> certResp) {
//Here new empty list is created i.e exp=[] //no elements inside
//Suppose your certResp=[B#12312,B#123834] i.e two B class objects
ArrayList<RespNode> exp = new ArrayList<RespNode>();
for (int i = 0; i< certResp.size(); i++) { //Size of certResp=2 as it contains 2 B objects
RespNode res=new RespNode(); //Create a RespNode class as you want to add of certResp ArrayList<RespNode>
res.setxxx(certResp.get(i)); //Take value of xxx method of certResp.get(i) i.e B object xxx method and set into res.setXXX or RespNode class
exp.add(res); //add res object into ArrayList
}
}
I have an array of objects. When the array fills up, I want to make a new array twice as large as the old one, and transfer all the elements over. I'm doing something wrong, I think its something to do with I'm not creating the correct reference to the new array. Here's my code, any help figuring this out would be appreciated.
private int DIRECTORY_SIZE = 6;
Entry [] directory = new Entry[DIRECTORY_SIZE];
private int numberOfElements = 0;
public int getNumOfElements(){
return numberOfElements;
}
public void setDirectorySize(int size){
DIRECTORY_SIZE = size;
}
public int getDirectorySize(){
return DIRECTORY_SIZE;
}
public void addEntry(String surname, String initial, String num) {
// TODO add an entry to an array, also increments numberOfElements variable tracking whats in array
if(getNumOfElements() == getDirectorySize()){ // if array is full
doubleArraySize(); // put temp values into new bigger directory array
}
int i = findFreeLocation();
directory[i] = new Entry(surname, initial, num);
numberOfElements++;
}
private void doubleArraySize(){
Entry[] temp = new Entry[DIRECTORY_SIZE]; //make new temp array same size as old one
for(int i = 0; i < DIRECTORY_SIZE ; i++){
temp[i] = directory[i]; // cycle through array putting all values into temp
// works up to here
}
setDirectorySize(DIRECTORY_SIZE*2); // double size of array
Entry[] directory = new Entry[DIRECTORY_SIZE]; // create new, double size directory array
for(int i = 0; i < temp.length ; i++){
directory[i] = temp[i];
}
}
private int findFreeLocation() {
int i;
for (i = 0; i < DIRECTORY_SIZE; i++)
{
if(directory[i] == null)
{
break;
}
}
return i;
}
In doubleArraySize() function , this is the issue :
Entry[] directory = new Entry[DIRECTORY_SIZE];
// you are not assigning it to the class attribute directory
// instead you are creating a local array directory
Make the following change :
this.directory = new Entry[DIRECTORY_SIZE];
// this will assign the newly created array to the class attribute
Note : I personally prefer to use this pointer to refer to class attributes so that it makes my code more readable, and its clear to everyone that the variable in question is a class attribute rather than local variable.
**SIZE has already double by this point. No need to multiple by 2
I remember doing something exactly like this when I was making a Vector ADT. However, I used instance variables instead of methods in my code for element number and the capacity. I definitely didn't initialize a Vector inside a method for a Vector.
setDirectorySize(DIRECTORY_SIZE*2); // double size of array
Entry[] directory = new Entry[DIRECTORY_SIZE]; // create new, double size directory array
Isn't DIRECTORY_SIZE an instance variable? Because if it is, I don't think you can initialize an object using an instance variable from the object you are overwriting.
Putting my code into your context, it would look something like this:
private void doubleDirectorySize()
{
Entry[] new_array = new Entry[new_directory_size*2];
for (int i = 0; i < directory_size; i++)
{
new_array[i]= directory[i];
}
directory= new_array;
}
This only works if directory was initialized to null, though, moving the pointer directory to the new array.
I am getting the error now that BookCollection.java:67: error: incompatible types
collection[lastElement++] = b;
Also am not sure if my constructor is set up correctly? The directions were:
Constructor:
Given a parameter specifying the limit on the collection size, an empty book collection is created using the given parameter. The parameter should not exceed the preset maximum size 200.
Am I initializing my variables correctly then? An answer below helped me change my code, but although I do not get errors within my constructor, I feel as though it may not be correct according to the directions....
I'll paste the couple chunks of my code that pertain to the question.
public class BookCollection{
//data fields, need complete
private int limit = 200;
//Array of type book
private int Book[];
//actual size of collection, initialized to zero. Must never exceed limit
private int collection[];
private int lastElement;
//Constructor
public BookCollection(int l, int c[], int le,int b[]){
Book = b;
collection = c;
limit = l;
lastElement = le;
int lastElement = 0;
if(limit <= 200){
Book[] collection = new Book[limit];
} else{
throw new UnsupportedOperationException("CannotExceedLimit");
}
}
ANNDDDD where I am getting the error:
public void addBook(int b[], int c[]) {
Book = b;
collection = c;
if (lastElement == collection.length) {
throw new UnsupportedOperationException("CorrectionFull");
}
for (int i = 0 ; i != lastElement ; i++) {
if(b.equals(collection[i])) {
throw new UnsupportedOperationException("DuplicateBook");
}
}
collection[lastElement++] = b;
}
You have not declared i as an integer in your for loop. So add the declaration with initialization. Replace this
for(i=0; i<collection.length; i++){
with
for(int i=0; i<collection.length; i++){
This statement
BookCollection[] collection = new BookCollection[limit]; //initialize array of 200
declares a local array. It gets destroyed as soon as you leave the constructor.
The collection that stays around is this one:
private int collection[];
It consists of ints, so when you try to do this
collection[i].add(b);
the compiler correctly complains that int does not have a method called add.
Good chances are, even declaring the collection as
private Book[] collection;
and initializing it in the constructor as
collection = new Book[limit];
is not going to help, though: unlike collections, Java arrays do not let you change their size dynamically, so you need to store an index of the last element of the collection[] array that has been set.
This leads to understanding that you need a loop for finding duplicates, and noting else: define an element int lastElement, set it to zero in the constructor, and rewrite the addBook method as follows:
public void addBook(Book b) {
if (lastElement == collection.length) {
throw new UnsupportedOperationException("CorrectionFull");
}
for (int i = 0 ; i != lastElement ; i++) {
if(b.equals(collection[i])) {
throw new UnsupportedOperationException("DuplicateBook");
}
}
collection[lastElement++] = b;
}
You did't declared i as a int type variable, make it as
for(int i=0; i<collection.length; i++){
^here
//...
}
I have a class holding a boolean, and two doubles, and then an array of that class, I need the boolean and doubles to have defaults values of false, 0.0, and 0.0, and then I have function that refers to an element of the array and the moment I try to access an one of the variables from the class it throws an exception saying its null. Here is my class and my function calling it.
public class PanelData {
boolean flag = false;
double tempStart = 0.0;
double tempEnd = 0.0;
}
private PanelData[] panelInfo = new PanelData[115];
private void panelInfoHandler (int i, double timeStart, double timeEnd) throws SQLException
{
if (!panelInfo[i].flag) {
delete();
insert();
panelInfo[i].flag = true;
panelInfo[i].tempStart = timeStart;
panelInfo[i].tempEnd = timeEnd;
}
else if (panelInfo[i].tempStart <= timeStart && panelInfo[i].tempEnd >= timeEnd) {
}
else
{
insert();
panelInfo[i].tempStart = timeStart;
panelInfo[i].tempEnd = timeEnd;
}
}
here is how I call the class.
panelInfoHandler(9, parsedStart, parsedEnd);
new PanelData[115] creates an array of 115 null references. Have you populated panelInfo with references to actual objects?
At a minimum, you then need to loop through that array and create new instances of PanelData for each element in the array, e.g.
for (int i = 0; i < panelInfo.length; i++)
panelInfo[i] = new PanelData();
Your array is full of null elements until you initialize it. To clarify, if you create an array of primitive objects, you get an array of default (i.e. 0) values. However, an array of Objects gets created with null elements.
int[] myIntArray = new int[10]; // 10 default values of 0
Integer[] myIntegerArray = new Integer[10]; // 10 null elements
add this line and then assign the values:
if(panelInfo[i] == null) panelInfo[i] = new PanelInfo();
You need to do something like
for(int i=0;i<115; i++)
{
PanelInfo[i] = new PanelData();
}
(Or whatever is the correct Java Syntax)
public class PanelData {
boolean flag = false;
double tempStart;
double tempEnd;
public PanelData() {
flag = false;
tempStart = 0.0;
tempEnd = 0.0;
}
private PanelData[] panelInfo = new PanelData[115];
for(int i = 0; i < 115; i++)
panelInfo[i] = new PanelData();
Creating the default constructor lets you instantiate the variables with the default values (false, 0.0, 0.0) in this case so you can test if you are getting a vanilla object back or not.