Results 1 to 7 of 7
  1. #1
    GuiRitter is offline Member
    Join Date
    Mar 2011
    Posts
    8
    Rep Power
    0

    Default 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:")));
                lista.add(fx,cobaia);
            } // tag 1
        }
        public void cálculo(){
            for(int fx = 0; fx < 2; fx++){
                cobaia = (Cobaias) lista.get(fx); // tag 2
                totalx = totalx.add(cobaia.ncobaia());
                if(cobaia.tcobaia().compareTo(new BigDecimal("1")) == 0){
                    totalc = totalc.add(cobaia.ncobaia());
                }else if(cobaia.tcobaia().compareTo(new BigDecimal("2")) == 0){
                    totalr = totalr.add(cobaia.ncobaia());
                }
            }
            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. #2
    Zack's Avatar
    Zack is offline Senior Member
    Join Date
    Jun 2010
    Location
    Destiny Islands
    Posts
    692
    Rep Power
    4

    Default

    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:")));
                lista.add(fx,cobaia);
            } // 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
                totalx = totalx.add(cobaia.ncobaia());
                if(cobaia.tcobaia().compareTo(new BigDecimal("1")) == 0){
                    totalc = totalc.add(cobaia.ncobaia());
                }else if(cobaia.tcobaia().compareTo(new BigDecimal("2")) == 0){
                    totalr = totalr.add(cobaia.ncobaia());
                }
            }
            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. #3
    GuiRitter is offline Member
    Join Date
    Mar 2011
    Posts
    8
    Rep Power
    0

    Default

    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. #4
    Zack's Avatar
    Zack is offline Senior Member
    Join Date
    Jun 2010
    Location
    Destiny Islands
    Posts
    692
    Rep Power
    4

    Default

    Quote Originally Posted by GuiRitter View Post
    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. #5
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    25

    Default

    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. #6
    GuiRitter is offline Member
    Join Date
    Mar 2011
    Posts
    8
    Rep Power
    0

    Default

    Quote Originally Posted by Zack View Post
    Good luck!
    Thanks!

    Quote Originally Posted by Fubarable View Post
    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. #7
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    25

    Default

    Quote Originally Posted by GuiRitter View Post
    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.

Similar Threads

  1. Strange unreachable statement error...
    By silafirion in forum New To Java
    Replies: 5
    Last Post: 12-11-2010, 05:05 AM
  2. Strange Compilation Error About Generics
    By dhafirnz in forum Advanced Java
    Replies: 7
    Last Post: 11-16-2010, 08:54 AM
  3. Strange Error
    By AJArmstron@aol.com in forum New To Java
    Replies: 1
    Last Post: 04-18-2010, 09:31 PM
  4. strange Error message
    By little_polarbear in forum New To Java
    Replies: 4
    Last Post: 08-25-2008, 11:45 PM
  5. System.in.read(); strange error!
    By kantze in forum New To Java
    Replies: 2
    Last Post: 03-19-2008, 01:44 PM

Posting Permissions

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