Enhanced for loop unable to initialize object - java

protected Day[] days= new Day[n];
for(int i=0;i<days.length; i++)
{
days[i]= new Day(5);
}
Above mentioned code works fine for me but modified for loop as mentioned below results in NullPointerException when I try to access the elements of the array. Can anyone explain why does it happens?
protected Day[] days= new Day[n];
for(Day d:days)
{
d= new Day(5);
}

When Java sees the enhanced for loop that you've made, it runs whatever you put inside it and makes a new variable (called d) and gives this variable a value of whatever is inside of your array. When you set d equal to a new Day(5); you are changing the value of the variable d, not the value inside the array. Here is a workaround:
protected D[] days = new Day [n];
for(int i = 0;i<days.length;i++)
days[i] = new Day(5);
This reaches into the actual array to set values. Hope this helps!

Loop variable in enhanced for loop is temporary. Assigning it inside loop body has no effect on the original item. Here is what happens to the loop according to Java Language Specification:
Day[] days = ...
for (int i = 0; i < days.length; i++) {
Day d = days[i];
...
}
When you assign d, it changes the local variable d, not days[i], which isnearly always an error. For that reason, some programming shops adopt a practice of making loop variable of enhanced for loop final:
for(final Day d:days) {
d= new Day(5); // <<== Compile-time error
}
If you want to shorten the code by avoiding the loop, use
Arrays.setAll(days, i -> new Day(5));

Second type of for uses Iterator for iterating by elements. Initializing reference d makes no sence, because this operation doesn't change reference inside your array.

Related

Difference between defining variables inside and outside loops

In terms of style or performance, is it better to define variables within loops or outside of them?
For example:
int var;
for (...) {
var = /*something*/;
// Code that uses var
}
or
for (...) {
int var = /*something*/;
// Code that uses var
}
If you have any insight on how variable declarations work internally, and how one of these might perform better than the other (even if it's only slightly), please share. And outside of performance, which style is preferred?
Inside
for(int i = 0; i < array.length; i++) {
final String variable = array[i];
}
Keeps scope of variables limited.
Variable can be final
More readable (maybe)
Outside
String variable;
for(int i = 0; i < array.length; i++) {
variable = array[i];
}
Variable is accessible outside loop.
For Each
for(final String variable : array) {
}
Only allocates once (source needed)
Keeps scope of variable limited.
Looks frickin' awesome.
Performance
The following test was run. It takes approximately 30s to run. The results show that there is no difference in performance between defining the variable inside or outside of the loop. This is most likely due to compiler optimizations. YMMV.
final double MAX = 1e7;
long start = System.nanoTime();
String var1;
for(double i = 0; i < MAX; i++) {
var1 = UUID.randomUUID().toString();
}
System.out.println((System.nanoTime() - start) / 1e9);
start = System.nanoTime();
for(double i = 0; i < MAX; i++) {
final String var2 = UUID.randomUUID().toString();
}
System.out.println((System.nanoTime() - start) / 1e9);
Discussion of Style Preference: https://stackoverflow.com/a/8803806/1669208
You should define for loop initialization variables in for loop header only which limits its scope within the loop. If you are concerned about performance then you should define variables within the loop.
Define variable outside loop only if you are using value of that variable outside loop as well.
Well, depends on how the variable is intended to be used primarily, if you are defining a variable inside a loop you would need to initialize the variable before the first use of the variable and in every run of the loop the variable would be re-initialized to this value.
On the other hand if you want to value of the variable to persist among different runs in the loop then you have to declare it outside. I don't think performance and style could be the primary criteria here.
If you declare the variable inside the for loop you won't be able to access it outside the loop.
for (...) {
int var = /*something*/;
// Code that uses var
}
you cannot access var outside the loop.
int var;
for(...) {
var = /*something*/;
// Code that uses var
}
var can be accessed outside the loop. Any other class code can use the value of var being set in the for loop.
Bottom line it all depends on your requirements.
The only time you should try to move the variable outside the loop, even if it's never used outside the loop is if you can re-use an object, and avoid using new on every iteration of the loop.
StringBuilder builder = new StringBuilder();
for(...) {
builder.append(..);
builder.append(..);
strings[i] = builder.toString();
// reset builder, to be used again
builder.setLength(0);
}
This is much more efficient than making a new StringBuilder every time.
In all other cases, you should prefer to declare variables inside the loop if you can

Why can I create multiple instances with the same name in a loop?

I don't understand why this works and I hope somebody can explain it to me.
Here is an example:
TestObject array[] = new TestObject[10];
for(int i= 0; i <= 10; i++){
TestObject object = new TestObject();
object.setValue(i);
array[i] = object;
System.out.println(array[i].getObject());
}
Why can I create multiple instances of "TestObject" with the same name in the loop?
Usually you can't create instances with the same name:
TestObject o = new TestObject(1);
TestObject o = new TestObject(2);
Well, this will obviously throws an error...
The scope for a for loop is limited to the iteration. So TestObject object is created and destroyed in each iteration.
Every iteration of a loop is a block and, as a block, has its own scope. You can achieve the same result by doing this:
{
int i = 0;
}
{
int i = 1;
}
// etc
This is because 'object' is in visibility scope of current loop iteration, so for next iteration, there can be initialized a new one with the same name (other scope).
it's the scope of object problem. every iteration has its scope let's say they are not the same object at all

Java - Why am I getting this NullPointerException?

I don't understand why this is giving me a null pointer exception when I try to add a value to the a1[i] array.
public class Array {
String text;
int total = 0, count = 0;
Array[] a1 = new Array[100];
Scanner scan = new Scanner(System.in);
public void setData() {
int i=0;
System.out.println(a1.length);
do {
System.out.println("Enter some data: ");
text = scan.next();
if (text.equals("end"))break;
a1[i].text = text; //I get a null pointer exception here. Not sure why.
i++;
} while (true);
}
Everything initialized in the a1 array is null. You'd have to put a new instance of Array() in there before doing anything with the member methods.
What this translates to: Every time you want to do something with a1[i], you'd have to have a new instance of Array in there first.
Example:
for(int i = 0; i < n; i++) {
a1[i] = new Array();
}
Because there isn't an object stored at a1[i]. What you're essentially saying at that line is:
null.text = text
which will break every time
You are getting a null-pointer exception, because you have allocated the space for 100 array elements, but you still need to initialize them:
So before accessing a1[i].text you need to initialize it by calling a1[i] = new Array()
Also I am quite sure, that you actually wanted to create some other kind of object, not Array. Array the class you are currently writing, as I understand, so you probably want to have multiple Strings, e.g. String[].
I recommend to you to use a LinkedList instead.
Array[] a1 = new Array[100]; //here you just create an array of references to objects which are set to null
a1[i].text = text; //before this line you should assign to a1[i] a reference to Array object for example a1[i] = new Array();

How come the array of objects I'm creating is a set of nulls?

So I'm creating a class called dicegame. Here's the constructor.
public class dicegame {
private static int a, b, winner;
public dicegame()
{
a = 0;
b = 0;
winner = 2;
}
And now in the main, I'm creating an array of this object (I called it spaghetti for fun).
public static void main(String[] args)
{
dicegame[] spaghetti = new dicegame[10];
spaghetti[1].roll();
}
But when I try to do anything to an element in the array, I'm getting the NullPointerException. When I tried to print one of the elements, I got a null.
You created an array, but you have to assign something (e.g. new dicegame()) to each element of the array.
My Java is slightly rusty, but this should be close:
for (int i=0; i<10; i++)
{
spaghetti[i] = new dicegame();
}
new dicegame[10]
just creates an array with 10 empty elements. You still have to put a dicegame in each element:
spaghetti[0] = new dicegame();
spaghetti[1] = new dicegame();
spaghetti[2] = new dicegame();
...
You need spaghetti[1]=new dicegame() before you call roll() on it.
Right now you are allocating an array,but don't. Place any objects in this array, so by default java makes them null.
1.you have just declared the array variable but not created the object yet. try this
2.you should start index with zero not with one.
dicegame[] spaghetti = new dicegame[10]; // created array variable of dicegame
for (int i = 0; i < spaghetti.length; i++) {
spaghetti[i] = new dicegame(); // creating object an assgning to element of spaghetti
spaghetti[i].roll(); // calling roll method.
}
Firstly,you should create object for every spaghetti input of yours.
You can start with whatever value you want. Just be sure that the size of array is matched accordingly so that you won't get ArrayIndexOutOfBounds Exception.
So,if you wanted to start with 1 and have 10 objects of the class dicegame,you will have to assign the size of the array as 11(since it starts from zero).
your main function should be like :
public static void main(String[] args)
{
dicegame[] spaghetti = new dicegame[11];
//the below two lines create object for every spaghetti item
for(int i=1;i<=11;i++)
spaghetti[i]=new dicegame();
//and now if you want to call the function roll for the first element,just call it
spaghetti[1].roll;
}

How can I initialize an array with an enhanced for-loop?

I was optimizing an application and wanted to change my for loops to enhanced loops:
From:
for (int m = 1;m < MAX_BEREN;m++)
{
Wasberen[m] = new Wasbeer();
Wasberen[m].YYY = r.nextInt(SchermY - 28);
}
to:
for (Wasbeer a : Wasberen)
{
if (a!=null)
{
a = new Wasbeer();
a.YYY = r.nextInt(SchermY - 28);
}
}
I get a NullPointerException, because it probably doesnt know how much 'beren' can be in
the array, but I'm not sure how to manage the same as the loop above (MAX_BEREN = 11).
If the array reference ('Wasberen' in this case) in an enhanced for statement is null, then a NullPointerException will result when the statement is executed.
For initializing arrays, you should stick to the syntax you had before.
You can't use the enhanced for-loop in Java to fill an array. (I'm assuming your Wasberen array was already created before - if not, this will get you a NullPointerException in both variants.)
Your code (simplified)
for (Wasbeer a : Wasberen)
{
a = ...;
}
is equivalent to
for (int i = 0; i < Wasberen.length; i++)
{
Wasbeer a = Wasberen[i];
a = ...;
}
This assignment will change the local variable a, but will have no effect on the contents of the array.

Categories

Resources