# Thread: Strange Error Regarding Lists and Variables

1. Member
Join Date
Mar 2011
Posts
10
Rep Power
0

## Strange Error Regarding Lists and Variables

Hi all.

It's my fourth day at my Java class at university and I stumbled upon an error that not even my teacher have been able to solve. Here's the code:

Java Code:
```// start of Cobaias.java

package ex2;

import java.math.BigDecimal;
import java.math.BigInteger;

public class Cobaias {
private BigDecimal ncobaia = new BigDecimal("0");
private BigDecimal tcobaia = new BigDecimal("0");
public void ncobaia(BigDecimal p){ ncobaia = p; }
public BigDecimal ncobaia(){ return ncobaia; }
public void tcobaia(BigDecimal p){ tcobaia = p; }
public BigDecimal tcobaia(){ return tcobaia; }
}

// end of Cobaias.java

// start of Main.java

package ex2;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;

public class Main {
private List lista = new ArrayList();
private Cobaias cobaia = new Cobaias(); // = (Cobaias) lista.get(0);
private BigDecimal totalx = new BigDecimal("0");
private BigDecimal totalc = new BigDecimal("0");
private BigDecimal totalr = new BigDecimal("0");
private BigDecimal porctc = new BigDecimal("0");
private BigDecimal porctr = new BigDecimal("0");

public Main(){
leitura();
cálculo();
exibição();
}
public static void main(String[] args) {
new Main();
}
public void leitura(){
for(int fx = 0; fx < 2; fx++){
cobaia.ncobaia(new BigDecimal(JOptionPane.showInputDialog("E" + (fx+1) + ": Digite a quantidade de cobaias utilizadas na experiência:")));
cobaia.tcobaia(new BigDecimal(JOptionPane.showInputDialog("E" + (fx+1) + ": Digite 1 se utilizou coelhos e 2 se utilizou ratos:")));
} // tag 1
}
public void cálculo(){
for(int fx = 0; fx < 2; fx++){
cobaia = (Cobaias) lista.get(fx); // tag 2
if(cobaia.tcobaia().compareTo(new BigDecimal("1")) == 0){
}else if(cobaia.tcobaia().compareTo(new BigDecimal("2")) == 0){
}
}
porctc = totalc.multiply(new BigDecimal("100")).divide(totalx);
porctr = totalr.multiply(new BigDecimal("100")).divide(totalx);
}
public void exibição(){
String print = "";
print += "Total de cobaias utilizadas: " + totalx + "\n\n";
print += "Total de coelhos utilizados: " + totalc + "\n";
print += "Total de ratos utilizados: " + totalr + "\n";
print += "Porcentagem de coelhos utilizados: " + porctc + "%\n";
print += "Porcentagem de ratos utilizados: " + porctr + "%";
JOptionPane.showMessageDialog(null, print);
}
}

// end of Main.java```
At the commentary "tag 1", if I print "tcobaia" from the object "cobaia", which have received the value directly, I'll get the right value. But at "tag 2", if I print "tcobaia" from the object "cobaia", which have received the object from the list, all "tcobaia" will have the same value as the last one.

What's wrong?

(If you have trouble understanding the error, "compile" the code. I use NetBeans.)
Last edited by GuiRitter; 03-29-2011 at 06:07 PM.

2. Alright, so... I'm not sure how far into Java programming you are, so I'll try to make this simple.

When you declare this variable:
private Cobaias cobaia = new Cobaias();
...then you declare it for the entire class. It becomes a global object to everything in that class. This means that in the loop indicated by "tag 1", you are editing the same object twice.

In some languages, this would be fine; however, in Java, everything is passed by reference; that means that, even though the "cobaia" has been passed to the array, calling those methods on it still modifies it.

The solution to this issue is rather simple; you must re-declare a NEW cobaia object for each iteration of the loop. Such as:
Java Code:
```    public void leitura(){
for(int fx = 0; fx < 2; fx++){
[color=red]Cobaias cobaia = new Cobaias();[/color]
cobaia.ncobaia(new BigDecimal(JOptionPane.showInputDialog("E" + (fx+1) + ": Digite a quantidade de cobaias utilizadas na experiência:")));
cobaia.tcobaia(new BigDecimal(JOptionPane.showInputDialog("E" + (fx+1) + ": Digite 1 se utilizou coelhos e 2 se utilizou ratos:")));
} // tag 1
}```

And you will also need to add a similar line in your second method:
Java Code:
```    public void cálculo(){
[color=red]Cobaias cobaia = null; // null because we don't have a reference... yet![/color]
for(int fx = 0; fx < 2; fx++){
cobaia = (Cobaias) lista.get(fx); // tag 2
if(cobaia.tcobaia().compareTo(new BigDecimal("1")) == 0){
}else if(cobaia.tcobaia().compareTo(new BigDecimal("2")) == 0){
}
}
porctc = totalc.multiply(new BigDecimal("100")).divide(totalx);
porctr = totalr.multiply(new BigDecimal("100")).divide(totalx);
}```

And lastly, you must remove the declaration that you already have (private Cobaias cobaia = new Cobaias();).

Hope that makes sense!

3. Member
Join Date
Mar 2011
Posts
10
Rep Power
0
I completely understood the first alteration. My knowledge on pointers in C++ helped a lot.

But for the second one, I didn't understood why
Java Code:
`Cobaias cobaia = null;`
is out of the for loop.

But thanks for the help already!

4. Originally Posted by GuiRitter
But for the second one, I didn't understood why
Java Code:
`Cobaias cobaia = null;`
is out of the for loop.
Actually, it can be inside as well. That's just a force of habit from doing it most efficiently; reassigning the value twice isn't strictly necessary, as you would do if you did this:
Java Code:
```// Inside the for loop:
Cobaias cobaia = null; // Done each time; but not necessary
cobaia = (Cobaias) lista.get(fx);```

You could also do this inside the for loop:
Java Code:
`Cobaias cobaia = (Cobaias) lista.get(fx);`
...and omit the = null altogether.

All three work, it's up to you which you use. Good luck!

5. I agree with all that Zack has said but have another unrelated question: Why are you using BigDecimals here? Isn't that a bit of overkill since ints and doubles would suffice nicely?

6. Member
Join Date
Mar 2011
Posts
10
Rep Power
0
Originally Posted by Zack
Good luck!
Thanks!

Originally Posted by Fubarable
I agree with all that Zack has said but have another unrelated question: Why are you using BigDecimals here? Isn't that a bit of overkill since ints and doubles would suffice nicely?
I've had many unhappy episodes in C/C++ because of the way floats work so I just prefer to use arbitrary precision arithmetic.

7. Originally Posted by GuiRitter
I've had many unhappy episodes in C/C++ because of the way floats work so I just prefer to use arbitrary precision arithmetic.
It's definitely overkill here. I urge you to use ints for your int input, doubles for your non-financial double inputs, and enums for your constants.

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•