Java Reference Issue - java

I'm very new to Java, so I'm sorry if this is a bit too stupid for you. So, I have a class called Construct that has an instance variable previousState. I have a setter in that class, with the signature setPreviousState.
Then, in an other class I set the previous State of a Construct object with this code :
ArrayList<Construct> sequence = new ArrayList<Construct>();
do {
Construct minimum = priorityQueue.delMin();
for (Construct neighbor : minimum.neighbors()) {
neighbor.setPreviousState(minimum);
priorityQueue.insert(neighbor);
}
System.out.println(minimum);
if (minimum.isGoalState()) {
// Construct sequence backwards and return it
sequence.add(minimum);
while(minimum.previousState() != null) {
sequence.add(0, minimum.previousState());
}
return sequence;
}
} while (true);
But while(minimum.previousState() != null) is an infinite loop because previousState() always references the same object. Why?

You never change the value of minimum in this loop, and it seems that the value of minimum.previousState() is also constant for each object [no side affects to method previousState()], you might want to add minimum = minimum.previousState(); to your while loop:
while(minimum.previousState() != null) {
sequence.add(0, minimum.previousState());
minimum = minimum.previousState();
}

Just because you never change what the minimum variable points to in the loop. So you're checking again and again that the same minimum's previousState is not null, without ever changing the minimum's value nor the minimum's previousState.

Related

Why isn't my object being added to my array?

I have a ManagementCompany data manager class that stores information about various properties in a Property (a class I defined) type array called properties[]. One of the methods of the class is meant to add properties to that array, and is called addProperty(Property p). It should take the given property and add it to the array in the first available space, if there is any (as seen here:)
Property[] properties = new Property[5];
public int addProperty(Property p) {
if (isArrayFull()) //Method returns true if there is no space, false otherwise
return -1;
else if (p == null) //Make sure p is valid
return -2;
for (int i = 0 ; i < properties.length; i++) { //Loop through all elements in the array
if (properties[i] == null) { //If the space is empty
properties[i] = new Property(p); //Assign a new property to it
return i; //Return the index of the new property
}
}
return -10; //Should never happen, but need it to compile
}
However, when I create and add properties to the array, only the first property is added. After the first property is added, the program doesn't continue adding to the first available space, instead, it seems to just ignore them. It doesn't replace the first one, and doesn't add it to the array (which is initialized to a length of 5). Any suggestions as to why?
Tests I'm running on it:
ManagementCompany mgmCmp = new ManagementCompany();
Property p1 = new Property("Property 1");
mgmCmp.addProperty(p1);
Property p2 = new Property("Property 2");
mgmCmp.addProperty(p2);
System.out.println(mgmCmp.toString());
The result is:
Property 1 null null null null
only the first property is added... Any suggestions as to why?
Because of return i;. You exit the method once you've added one property.
Hope that helps
Found a seemingly unrelated method in another class that was causing the object not to be stored in the array. Thanks for the advice.

checking and setting variable, efficiently

I am new to programming and have a simple question: is there a "better" or more efficient way of doing this...
if (x != 0) {
y = x;
}
or
if (getMethod() != null) {
value = getMethod();
}
I'm new to programming and above code (esp the 2nd one) seems inefficient.
Thanks in advance.
You second example can suffer from a "Time of check, to time of use" weakness. If the first invocation of getMethod() returns non-null, it is possible that your second invocation will return null. A better way to do it would be:
value = getMethod();
if(NULL != value)
{
/* use value as planned */
}
else
{
/* handle a null value, probably an error */
}
if interested, you can read more about TOCTTOU weaknesses here.
For your first example, I don't really see a better way of doing this.
N.B. This answer is from the perspective of a C programmer (seeing as how C was one of your tags).
Hope this helps
- T.
You can make it shorter
if ( x ) y = x;
is the same as
if (x != 0) {
y = x;
}
And
if ( getMethod() ) value = getMethod();
is the same as
if (getMethod() != null) {
value = getMethod();
}
First code snippet:
In C any non-zero value is treated as true and 0 treated as false. So, for the first example, you can rewrite it as:
if (x) {
y = x; // this line will be executed if x not equal to zero
}
Second code snippet:
You called getMethod() twice which is not efficient. As per your code, you are assigning the return value of getMethod() into value if getMethod() returns anything but NULL. So you can use a temporary variable to check the return value of getMethod(), like following:
temp = getMethod();
if (temp != null) {
value = temp;
}
That will reduce calling same method twice.

Initialising a variable in the while expression - not the statement

In the expression of a while loop, is it possible to initialise a variable, then use that as part of the expression?
It's probably simpler in code:
while (int a = someMethod(), a<b)
It would be possible to just add another method, and so have to following:
private boolean whileLoopTest() {
int a = someMethod();
return a<b;
}
public void originalMethod() {
while (whileLoopTest()) {
//...
but this doesn't seem as neat.
EDIT
I also don't want to directly compare the method to my variable, as it is compared to several variable, and so if would be a long, unreadable mess. A better example of what I want would be:
while (int a = SomeClass.someStaticMethod(), -1<a && a<b)
It's not true in my case, but this would be a equally valid question if someStaticMethod() took a long time to return - I would only want to call it once.
I'm fairly new to StackOverflow, so I'm not sure if giving other situations where this would apply is what I should be doing.
int a;
while((a = someMethod()) < b){
//do something
}
A common use for this is reading from a file:
BufferedReader fileIn = ...
String line;
while((line = fileIn.readLine()) != null){
//do something
}
fileIn.close();
/edit
You can do this for your new scenario:
int a;
while(-1 < (a = SomeClass.staticMethod()) && a < b) {
//do something
}
Once the left hand portion of the && statement is executed, the return value of SomeClass.staticMethod() is stored in a, which carries over the the right hand portion of the statement.
Why not just not assign the value to "a" if you are not using it anyways?
while (someMethod() < b) { doSomething() }
If you actually do need "a" then your alternate solution would not work. The solution then would be either to save it (which I do not consider unneat) or what Kerrek said.
You can use the function directly without using a local variable like this:
while ( someMethod() < b) { /* ... */}
This, if your method returns intended value. (If you are casting it to a local variable, it's supposed to)
EDIT: For your second question.
Your concern is understandable, but if you are assigning that methods value to a local variable inside while loop's boolean expression, in every loop where "While" checks the expression, you are assigning methods' return value to local variable, which means you are calling that method in every iteration. That doesn't change anything from my first answer.

Logical mistake or not?

I have written this function which will set
val=max or min (if val comes null)
or val=val (val comes as an Integer or "max" or "min")
while calling i am probably sending checkValue(val,"min") or checkValue(val,"max")
public String checkValue(String val,String valType)
{
System.out.println("outside if val="+val);
if(!val.equals("min") && !val.equals("max"))
{
System.out.println("Inside if val="+val);
try{
System.out.println("*Inside try val="+val);
Integer.parseInt(val);
}
catch(NumberFormatException nFE)
{
System.out.println("***In catch val="+val);
val=valType;
}
return val;
}
else
{
return val;
}
}
But the problem is if val comes null then
outside if******val=null
is shown.
Can any1 tell me is this a logical mistake?
And why will I correct?
If val is null, then the expression val.equals("min") will throw an exception.
You could correct this by using:
if (!"min".equals(val) && !"max".equals(val))
to let it go inside the if block... but I would personally handle it at the start of the method:
if (val == null) {
// Do whatever you want
}
Btw, for the sake of readability you might want to consider allowing a little more whitespace in your code... at the moment it's very dense, which makes it harder to read.
...the problem is if val comes null then outside if****val=null is shown. Can any1 tell me is this a logical mistake?
The output is correct; whether you want it to come out that way is up to you.
Your next line
if(!val.equals("min") && !val.equals("max")){
...will throw a NullPointerException because you're trying to dereference val, which is null. You'll want to add an explicit check for whether val is null:
if (val == null) {
// Do what you want to do when val == null
}
you should use valType instead of val to check either minimum or maximum is necessary to check.
My advice to you in such cases to use boolean value or enum instead of strings. Consider something like that:
/**
* check the value for minimum if min is true and for maximum otherwise
*/
public String checkValue(String val, boolean min){
if (min) {
// ...
} else {
// ...
}
}
If you need to compare strings against constants you should write it the other way around to make it null-safe:
if (! "min".equals(val))
And while this is mostly a style issue, I would make all method arguments final and not re-assign them (because that is confusing), and you can also return from within the method, not just at the end. Or if you want to return at the end, do it at the very end, not have the same return statement in both the if and the else branch.

Final initialization in java can be postponed, how does this prevent against returning null inadvertently?

In the "hidden features of java" question, someone mentions that final initialization can be postponed and provides an example:
public Object getElementAt(int index) {
final Object element;
if (index == 0) {
element = "Result 1";
} else if (index == 1) {
element = "Result 22";
} else {
element = "Result 3";
}
return element;
}
The poster says:
It's too easy to miss a case and return null by accident. It doesn't make returning null impossible, just obvious that it's on purpose.
However I cannot wrap my head around what this means. How is this any different if element was not declared final? Wouldn't the else statement always ensure that null is not returned? I'm thinking this is more a cosmetic thing rather than actually effecting the way the code operates.
The way you posted the question, the poster seems to be saying that if you did:
Object element = null;
And then set it via the if methods, you could return null by accident (if you didn't construct your else statement correctly), so take advantage of the fact that final initialization can be differed to after declaration.
However, the example is superfluous, because the compiler guarantees that this variable will be set before being used because it is local.
More interesting would be a case like this:
public class SomeClass {
private final Object element;
public SomeClass(int index) {
if (index == 0) {
element = "Result 1";
} else if (index == 1) {
element = "Result 22";
} else {
element = "Result 3";
}
}
}
In that case the compiler will warn you if you never set element, rather than setting it to null for you, which is what would happen if it was not declared final.
In summary, what is interesting to know is that a final field or variable doesn't have to be set where it is declared (as you might be inclined to think). Final means that it can only be set to a given value once, not that it has to be set on the same line as it is declared.
Finals can only be set and never re-set. They are sometimes conflated with the concept of constants in java. More correctly they are immutable object references.
The catch is that if something is immutable, how and when do you set its initial value. The answer is that java checks that only one possible flow can assign a value to a final variable. That way you don't have to assign the value at declaration time.

Categories

Resources