Instantiation of Global fields [duplicate] - java

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 1 year ago.
I wrote a code for detecting cycle in graph.
The input is given such that there can be several lines with each line of form a # b .
It denotes that there is an edge from a to b.
My code worked and then I played with it a bit and came across a problem with line a and line c and with line b and line d.
When I combine line a and line c and write the declaration and instantiation together as "ArrayList[]" arr=new ArrayList[99999] , similarly line b and line d,then everything is working fine(Assuming I make appropriate changes like passing arr and visited as arguments between DFS and DFSvisit).
But If I write it as I have written below then I am getting Null pointer exception. What is the reason for this?
class Test {
ArrayList<Integer>[] arr; // line a
boolean[] visited; // line b
public static void main (String[] args) throws java.lang.Exception {
Test obj=new Test();
obj.DFS();
}
public void DFS() {
arr=new ArrayList[99999]; // line c
visited=new boolean[99999]; // line d
for(int i=0;i<99999;i++) {
arr[i]=new ArrayList<>(); //instantiate each element of "array of Arraylists"
}
boolean[] flag=new boolean[99999]; //a flag array to identify which elements of array are valid elements
Scanner sc=new Scanner(System.in);
while(sc.hasNext()) {
int a=sc.nextInt(); //take first number
sc.next(); //throw away "#" token
int b=sc.nextInt(); //take second number
flag[a]=true; //means arr[a] is valid
arr[a].add(b); //add b to adjaceny list of arr[a]
}
Test obj=new Test();
for(int i=0;i<99999 ;i++) {
if (flag[i]) { //call DFSvisit only if arr[i] is valid
obj.DFSvisit(i);
}
}
System.out.println("Cycle does not exist");
}
void DFSvisit(int i) { // basic DFS implementation
visited[i] = true;
for (int j=0;j<arr[i].size();) {
if (visited[arr[i].get(j)]==true) {
System.out.println("Cycle exists");
System.exit(0);
} else {
DFSvisit(arr[i].get(j));
}
j++;
}
visited[i] = false;
}
}
Error:
Exception in thread "main" java.lang.NullPointerException
at test.Test.DFSvisit(Test.java:59)
at test.Test.DFS(Test.java:49)
at test.Test.main(Test.java:18)
P.S. I know that If I try to use reference variable before it is initialised then I will get Null Pointer Exception. But here I am not able to see anywhere where that is happening. I have declared arr and visited as a member of class(outside every method). I am then initialising them after moving from main method to DFS method. In between I haven't tried to use either arr or visited but I am getting NPE anyway. Why is that?

You just got confused between two objects.
class Test {
ArrayList<Integer>[] arr;
boolean[] visited;
public static void main (String[] args) throws java.lang.Exception {
Test obj=new Test(); // here you create the first object. arr is null here
obj.DFS();
}
public void DFS() {
arr=new ArrayList[99999];
visited=new boolean[99999]; // here you initialize the fields of the first instance of the object
...
Test obj=new Test(); // here you create the second instance of the object. arr is null
for(int i=0;i<99999 ;i++) {
if (flag[i]) {
obj.DFSvisit(i); // here you call the method of the second object where arr is null. NPE
}
}
If you combine the lines, then the field initialization will happen during the object construction. That's why no NPE there.

Related

changes to a variable dont remain outside the loop & variables dont inherit to other classes

What I want to do: read strings from keyboard using Scanner until specific string is used to break the infinite loop. save them in an arrayList, then pass them into an array with its length beeing the number of the iteration of the loop
public class InputReader {
ArrayList<Integer> list = new ArrayList<>(0);
int arrayLength;
String readInput;
Scanner ir = new Scanner(System.in);
void readInput() {
for (int m=0; ;m++) {
readInput = ir.nextLine();
if ("q".equals(readInput)) {
//problem: arrayLength does not have the value of m outside the loop
arrayLength = m;
break;
}
System.out.println("arrayLength: "+arrayLength);
intInput = Integer.parseInt(readInput);
list.add(intInput);
}
}
int[] array = new int[arrayLength];
}
}
Inside the loop arrayLength works perfectly but outside the loop it has no value as I initialized it without value. Because of this,
System.out.println("array.length: "+array.length);
always returns 0 and the compiler returns this error:
java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
when I try to save integers inside the array.
1) How can I make the changes to the variable stay outside the loop?
2) Weird observation A:
int[] array = new int[list.size()];
returns the same error despite list.size() having the right value even outside the loop (checked by printing it).
And B: The code works if I create my array inside another method instead of inside the class and then use it in the method, but this way I cannot use it in my other classes despite using inheritance or parameters.
void giveOutput() {
int[] array = new int[list.size()];
public void giveOutput () {
System.out.println("list.size()"+list.size());
System.out.println("array.length:"+array.length);
for (int n=0; n<list.size(); n++) {
array[n] = list.get(n);
System.out.print("array["+n+"]:"+array[n]+" ");
}
}
}
this creates a working array but I cant hand it over to my Minsort extends InputReader subclass where it is sorted which leads to question number
3) How to use variables initialized in methods in other classes? This way my program could work too.
(I am a bloody beginner, started seriously working with java yesterday, my first succesful project was a Minsort-Algorithm I wrote from scratch so please have mercy. And thanks in advance.)
The array array is initialized when an object of the type InputReader is instantiated, not after the readInput() method is run.
In other words, array is always initialized when you use new InputReader(), not after the readInput() method is run. That means that the arrayLength variable has not yet been modified at the moment when array is created, so the default value for an int is used, which is 0.
Try this:
public static class InputReader {
ArrayList<Integer> list = new ArrayList<>(0);
int arrayLength;
String readInput;
Scanner ir = new Scanner(System.in);
int[] array;
void readInput() {
for (int m=0; ;m++) {
readInput = ir.nextLine();
if ("q".equals(readInput)) {
//problem: arrayLength does not have the value of m outside the loop
arrayLength = m;
break;
}
int intInput = Integer.parseInt(readInput);
list.add(intInput);
}
System.out.println("arrayLength: "+arrayLength);
array = new int[arrayLength];
}
}
Also, your System.out.println("arrayLength: "+arrayLength); always returned 0 because the arrayLength changes only when q is pressed.
To answer your third point: You could create a getter function in the class InputReader. For example:
public int[] getArray() {
return array;
}
As a side-note: It is very good practice to have your instance variables be declared with a private access modifier, and to then create public getter and setters. This is called Encapsulation, and is an OOP principle (my advice is that you google the OOP principles).
More info about getters and accessors here: Why use getters and setters/accessors?

Using an array in a recursive algorithm to find combinations

The idea is if i am at a certain stair i can either go one step down or two so if am at stair 3 i can go down 1 1 1 or 2 1 for example. My code should print all the possibilities. The error I get is that I can't convert the add function to an array (since the add method is a boolean). What is wrong with this algorithm?
public class Stairs {
public static void staircase (int height ){
ArrayList<Integer> Array = null;
explore (height,Array);
}
public static void explore(int objheight,ArrayList<Integer>Array){
int intialheight = 0;
if (intialheight == objheight){
Array.toString();
}
else{ if (objheight > intialheight ){
explore(objheight-2,Array.add(2));
explore(objheight-1,Array.add(1));
}
}
after your feedback I am getting an empty output
import java.lang.reflect.Array;
import java.util.ArrayList;
public class Stairs {
public static void staircase (int height ){
ArrayList<Integer> Array = new ArrayList<Integer>();
explore (height,Array);
}
public static void explore(int objheight,ArrayList<Integer>Array){
int intialheight = 0;
if (intialheight == objheight){
Array.toString();
}
else{ if (objheight > intialheight ){
Array.add(2);
explore(objheight-2,Array);
Array.add(1);
explore(objheight-1,Array);
}
}}
public static void main (String args[]){
staircase(3);
}
}
The method add(E e) in ArrayList returns true upon appending the element e passed as a parameter to the end of the ArrayList.
Your method, explore(int objHeight, ArrayList<Integer> Array) does not accept a boolean for its second parameter. Yet, in that same method, explore, you are recursively calling explore and passing in a boolean to the method.
The following code should be modified to first invoke the add method of Array and then pass Array to the explore method.
Before:
explore(objheight-2,Array.add(2)); This code is passing parameters int and boolean to the explore method, which is not the parameters it accepts. You should instead attempt the following.
After:
Array.add(2);
explore(objheight-2,Array); This code first adds 2 to the Array and then passes the Array to the explore method without invoking any further methods on the Array object.
You will also need to do this for the next line of code, where you have explore(objheight-1,Array.add(1));.
Edit: Upon further examination of the code, I discovered another (sooner) error that occurs. A NullPointerException will occur each time the program runs:
ArrayList<Integer> Array = null;
explore (height,Array);
Then inside the explore method, different methods on Array are invoked, despite Array always being null:
Array.toString();, Array.add(2) and Array.add(1).
The Array object must be initialized inside of either the staircase or explore methods.
ArrayList<Integer> Array = new ArrayList<Integer>(); or ArrayList<Integer> Array = null;
Array = new ArrayList<Integer>();

Null Pointer Exception / Arrays

I get a NPE in the 2 lines I commented "NPE HERE"
import javax.swing.*;
import java.awt.*;
public class Project1{
static TextArea preSort, postSort;
static String[] Array = new String[20];
public static void main(String[] args) {
Project1GUI myFrame = new Project1GUI("Project1GUI");
readStringFromFile("filename.txt");
enterFirst(Array); // NPE HERE
selectionSort(Array);
enterSecond(Array);
}
public static void enterFirst (String[] name){ // NPE HERE
for(int i=0;i<name.length&&name[i]!=null;i++)
preSort.append(name[i]+" ");
}
public static void enterSecond (String[] name){
for(int i=0;i<name.length&&name[i]!=null;i++)
postSort.append(name[i]+" ");
}
public static void selectionSort (String[] name){
for(int i=0; i<name.length-1&&name[i]!=null;i++){
int indexLowest=i;
for (int j=i+1; j<name.length&&name[j]!=null;j++)
if(name[j]<name[indexLowest])
indexLowest=j;
if(name[indexLowest]!=name[i]){
String temp = name[indexLowest];
name[indexLowest]=name[i];
name[i]=temp;
}//if
}//for
}//method selectionSort
public static boolean isOkay (String name){
char[] chars = name.toCharArray();
for(int i=0; i<chars.length; i++){
if(!Character.isLetter(chars[i])){
return false;
}
}
return true;
} //isOkay
public static void readStringFromFile(String fileName){
TextFileInput inFile = new TextFileInput(fileName);
String line;
line = inFile.readLine();
int index = 0;
while (line!=null) {
if(isOkay(line))Array[index++]=line;
else System.out.println(line);
line = inFile.readLine();
}//while
inFile.close();
}
} //Project1
I have 2 other classes in my directory, TextFileInput and my GUI class (do you guys need to see the code there too?).
I probably have more mistakes in my code, not sure as I'm still not very familiar with Java and am trying my best to learn. Any other advice will be appreciated.
Anyways, what is causing the NPE? From my understanding, my string array has null values that cause a NPE when I try to access the array with name[i].
I've tried filling up the rest of my array with dummies (strings with value of "antinull") but that didn't solve anything and would clearly not be an elegant solution even if it was one.
I just need to have a project1 class and a GUI class. The objective is to take in a file with strings, check if a string is all letters, and send the actual words to a text area in the GUI. Then sort by size and send the ordered version to the other text area. The strings that aren't words are sent to be output to the console. Project1 should have a constructor which takes one string parameter.
When you call preSort.append(...), you're calling a method from a variable (preSort), which is not initialized and thus null, this causes a NullPointerException. If you initialize preSort in your main method for instance, things will work better.
You should also look into indenting your code properly and use proper Java naming standards. Variables should be camelCased, not starting with a capital letter.
I don't think you are getting a Null Pointer Error on calling enterFirst(Array). The loop shouldn't even execute since the first value of Array is a null. But you might get a Null Pointer Error because preSort variable doesn't refer to any object.
Try:
static TextArea preSort = new TextArea(5, 20); and
static TextArea postSort = new TextArea(5, 20);

Void function returns changed array, but not a changed integer? [duplicate]

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 7 years ago.
{
int[] n = new int[4];
n[0]=1;
n[1]=3;
n[2]=4;
n[3]=5;
for(int i=0; i<4; i++)
{
System.out.print(n[i]+ " ");
}
menjava(n);
System.out.println();
for(int i =0;i<4;i++)
{
System.out.print(n[i]+ " ");
}
}
public static void menjava(int[] a)
{
a[0]=1*10;
a[1]=3*10;
a[2]=4*10;
a[3]=5*10;
}
}
http://imgur.com/0CNqY9A //the result in console
{
int n = 1;
System.out.println(n);
menjava(n);
System.out.println(n);
}
public static void menjava(int st)
{
st = 4;
}
}
http://imgur.com/dAqzuez //the result in console
So why did the Array get returned, but the integer stayed the same (whcih in my mind should). I can't find anything on why the array get's returned in an void function.
The reference to the array is not returned nor changed.
The array referenced has been changed.
int[] n = new int[4];
In this code n is a reference to an array and this reference is copied when you pass it to a method. This reference is not changed.
Your issue here is that Java is a pass by value language. This means in your situation you are providing your method menjava with what might as well be a temporary array that contains the same values as your original array n. So when this array is passed to menjava it does the calculations, but to this temporary array that your main method doesn't know about.
The easiest fix here is to have your menjava method return the array it worked on and set your array to that value in the calling function something like this:
public static int[] menjava(int[] a){
//changes to array a
return a;
}
and then in your calling function:
{
//your other code
n = menjava(n);
//the rest of your code
}

Reading file and placing into array

I'm having troubles reading a file and then placing its contents into an array. The console says my error is here:
Exception in thread "main" java.lang.NullPointerException
at readFile.readFile(readFile.java:23)
at apples.main(apples.java:6)
However I do not now how to fix it.
import java.util.*;
import java.lang.*;
import java.io.*;
public class readFile {
private Scanner x;
public void openfile(){
try{
x = new Scanner( new File("/Users/Zachary/Desktop/chinese.txt"));
}
catch (IOException e){
System.out.println("you failed foo");
}
}
public void readFile(){
int y = 0;
int[] nums = null;
while(x.hasNext()){
for(y=0; y<10;y++) {
nums[y] = x.nextInt();
}
System.out.println(nums[y]);
}
}
public void closeFile(){
x.close();
}
}
public class apples {
public static void main (String[]args){
readFile r = new readFile();
r.openfile();
r.readFile();
r.closeFile();
}
}
You seem to have a NullPointerException at:
nums[y] = x.nextInt();
That is because of this line:
int[] nums = null;
It is null, so you can't put stuff in it. Here's a simple fix:
int[] nums = new int[10];
The above code will initialize nums so that it is an empty (not really - it's actually filled with 0) array like this:
---------------------
|0|0|0|0|0|0|0|0|0|0|
---------------------
If you want to be able to add as many numbers to it as you want, you will need an ArrayList (link).
Also, this code will throw an error:
for(y=0; y<10;y++) {
nums[y] = x.nextInt();
}
System.out.println(nums[y]);
That is because your System.out.println doesn't know what y is. Just move the System.out.println into the for loop so it can "see" y. (This is called scope)
The compiler error states that the error occurs at "readFile.java:23". This is line 23 of the file readFile.java. I believe that is this line:
nums[y] = x.nextInt();
The problem is that you declared nums as:
int[] nums = null;
When you try to access an array that is initialized to null, you should not be surprised to get a NullPointerException.
To fix the problem, you need to create an array object:
int[] nums = new int[SOME_SIZE];
You will need to provide the size yourself as you have not provided enough information for me to guess the value.
is the inner loop really necessary? you are looping x * 10 times which is really not a good way to assigned data.

Categories

Resources