views:

62

answers:

3

Greetings Stack Overflowers,

A while back, I was working on a program that hashed values into a hashtable (I don't remember the specifics, and the specifics themselves are irrelevant to the question at hand). Anyway, I had the following code as part of a "recordInput" method.

tempElement = new hashElement(someInt);

    while(in.hasNext() == true)
    {
        int firstVal = in.nextInt();
        if (firstVal == -911)
        {
            break;
        }
        tempElement.setKeyValue(firstVal, 0);
        for(int i = 1; i<numKeyValues;i++)
        {
            tempElement.setKeyValue(in.nextInt(), i);
        }

        elementArray[placeValue] = tempElement;
        placeValue++;

    }   // close while loop

} // close method

This part of the code was giving me a very nasty bug -- no matter how I finagled it, no matter what input I gave the program, it would always produce an array full of only a single value -- the last one.

The problem, as I later determined it, was that because I had not created the tempElement variable within the loop, and because values were not being assigned to elementArray[] until after the loop had ended -- every term was defined rather as "tempElement" -- when the loop terminated, every slot in the array was filled with the last value tempElement had taken.

I was able to fix this bug by moving the declaration of tempElement within the while loop. My question to you, Stackoverflow, is whether there is another (read: better) way to avoid this bug while keeping the variable declaration of tempElement outside the while loop.

(suggestions for better title and tags also appreciated)

A: 

Why would you want to keep the variable declaration outside the while loop? Anyway, you can, as long as you assign it to a new hashElement each time:

hashElement tempElement;
while (/*...*/) {
    tempElement = new hashElement();
    //...

It's certainly not "better" though. Scope your variables as narrowly as possible, in general.

Mark Peters
+1  A: 

This is not about declaration of the variable, but about the objects you create. Arrays in java only hold references to objects, so if you actually want to have distinct objects in the array, you need to create them with new somewhere in the loop.

tempElement = new WhateverClass();
unbeli
Or just `elementArray[placeValue] = new ...` and skip the temporary variable entirely.
Mark Peters
Not when you call setters on it. Calling setters like elementArray[placeValue].setWhatever(whatever) is ugly and deserves severe punishment.
unbeli
I think the temp var is necessary because the OP is doing operations on it that need to be done after construction.
Andrew Hubbs
@Andrew, unbeli: Necessary, no; ugly...depends. Agreed it can be bad style. But arrays in general are ugly and I don't see a reason here why it shouldn't be a `List` instead, replacing the assignment with an `add`.
Mark Peters
@Mark, arrays are just beautiful, fast and efficient. And, changing to a List does not solve the issue in question
unbeli
@unbeli: Indeed, the temporary variable would be required in the case of a List! But arrays are not beautiful or efficient here. The OP is guessing at how many elements there will be, and only filling up part of the array if he overestimated. Then probably using placeValue later on to find out how many there were, and then if he's smart copying to a new array that's the correct size. That's just gross. A List is the correct solution here. If an array is needed extract the array afterwards.
Mark Peters
A: 
Element tempElement;

while(condition){
    tempElement = new HashElement();

    //do more stuff

    elementArray[index] = tempElement;
}
Andrew Hubbs