1

A few days ago I asked this question, and now I have a more specific one, since I worked on my program some more and added a few things. Basically I start out with an empty ArrayList which is supposed to hold birthdays that are added via console. This part I got down + it prints the birthday I add. But if I want to add another one, it prints the first one I added again? How could I make it print out all the birthdays I have added this far? I'll show the code I have so far

Birthday class

public class Birthday {
    private String bdayKid;
    private int age;
    private boolean gift;
    
    public Birthday(String bdayKid, int age, boolean gift) {
        this.bdayKid = bdayKid;
        this.age = age;
        this.gift = gift;
    }
    
    //overridden toString() method
    public String toString() { 
        return this.bdayKid + " turns " + this.age + "! They are" + 
            (this.gift ? "" : "not ") + " getting a gift.";
    }
}

Main class

public class MainClass{
   public static void main(String []args) {
      ArrayList<Birthday> bdays = getBirthdays();
      printBirthdays(bdays);
   }

   //This method will return a list of birthdays
   public ArrayList<Birthday> getBirthdays() { 
      ArrayList<Birthday> bdays = new ArrayList<Birthday>();
      Scanner scan = new Scanner(System.in);
      
      //create a birthday
      Birthday bday = new Birthday(scan.nextLine(), scan.nextInt(), scan.nextBoolean());
      //add the birthday to arraylist of birthdays
      bdays.add(bday);

      
      return bdays;
   }

   //This method will print a list of birthdays
   public void printBirthdays(ArrayList<Birthday> bdays) {    
      //iterate through each birthday and print out the result 
      for (Birthday bday : bdays) {
         System.out.println(bday);
      }
   }
}

and inside a long-ish switch statement i added this option:

System.out.println("Do you want to add another birthday?");
                    boolean anotherOne = scan.nextBoolean();
                    if (anotherOne == true) {
                        getBirthdays();
                        printBirthdays(bdays);
                    }

Do I need to add an if statement inside my for-each loop? Any help is appreciated!

5
  • ehm ... your code is already doing what you are asking it to do, what more do you need? if you want more elements, just check your anotherOne in a while loop, and reset the value of anotherOne as last statement of that loop Commented Feb 22, 2021 at 14:27
  • "How could I make it print out all the birthdays I have added this far" <- Note that in your method getBirthdays() you create a new local variable ArrayList<Birthday> bdays and then add to that local variable and return it. Since every time you call that method you create a new local ArrayList those Lists will never contain more than one Birthday. Commented Feb 22, 2021 at 14:31
  • @OHGODSPIDERS oh no..how do i get around that? Commented Feb 22, 2021 at 14:34
  • Don't always create a new local object. Instead why not make the List a field of the class and initialize it in the constructor. Commented Feb 22, 2021 at 14:35
  • @Stultuske your explnation makes sense but when i look at my code i freeze T_T could you roughly explain what that would look like in code? i'm new to this sorry Commented Feb 22, 2021 at 14:36

3 Answers 3

1

You have a serious problem in understanding Java. First, you need to understand a concept, the scope of a variable.

If you create a variable inside a function, then the scope of the variable is in the function only.

You have different instances of ArrayList<Birthday> with the identifier bdays. One instance that you defined in void main function, and other instances are created each time you call getBirthdays() method. In the switch statement, when you call getBirthdays(), a new ArrayList<Birthday> is formed and returned by the function, while your original ArrayList<Birthday> bdays remains unchanged. And when you call printBirthdays(bdays) it takes argument as the array created by you in the first line of your main method instead of a new ArrayList returned by getBirthdays() method. Hence, it does not print the new Brithday. So, you can change your code something like follows:

Main class

public class MainClass{
   public static void main(String []args) {
      // Instantiate your one and only bdays array
      ArrayList<Birthday> bdays = new ArrayList<Birthday>();
      getBirthdays(bdays);
      printBirthdays(bdays);
   }

   //This method will return a list of birthdays
   public void getBirthdays(ArrayList<Birthday> bdays) { 
      Scanner scan = new Scanner(System.in);
      
      //create a birthday
      Birthday bday = new Birthday(scan.nextLine(), scan.nextInt(), scan.nextBoolean());
      //add the birthday to arraylist of birthdays
      bdays.add(bday);

      // Good practice to close a scanner
      scan.close();
   }

   //This method will print a list of birthdays
   public void printBirthdays(ArrayList<Birthday> bdays) {    
      //iterate through each birthday and print out the result 
      for (Birthday bday : bdays) {
         System.out.println(bday);
      }
   }
}

and,

System.out.println("Do you want to add another birthday?");
                boolean anotherOne = scan.nextBoolean();
                if (anotherOne == true) {
                    getBirthdays(bdays);
                    printBirthdays(bdays);
                }

Note that, Java passes objects as reference, so if you pass you **bdays** to getBirthdays(bdays) then every change inside this function done to bdays will also occur to your original bdays in main method. More precisely, they are the same ArrayList in your memory, and the variables bdays in two different methods main and getBirthdays(bdays) are just different identifiers referencing to same ArrayList<Birthday> that you created at the start of the function and passed as a reference to the getBirthdays method. Check other relevant tutorials on passing variables by reference in java.

Sign up to request clarification or add additional context in comments.

2 Comments

thank you so much for breaking the concept down for me! I know I should fully understand each concept before using it but I thought trying out things with a smallish project would be better practice. so yeah, thanks a lot, it's working! :]
You did the right thing, that's how we learn.
1

IMO the best way to do this is splitting your getBirthdays() to printBirthdays() and addBirthday(). Here is the code and you can use your own logic to loop the input:

import java.util.ArrayList;
import java.util.Scanner;

public class MainClass {
    static ArrayList<Birthday> bdays = new ArrayList<>();
    public static void main(String []args) {

        while(true) {
            //Use this method every time you need to add new BDay
            addBirthday();
            //Use this method to print all BDays in ArrayList
            printBirthdays();
        }
    }
    public static void addBirthday(){
        Scanner scan = new Scanner(System.in);
        Birthday bday = new Birthday(scan.nextLine(), scan.nextInt(), scan.nextBoolean());
        bdays.add(bday);
    }
    public static void printBirthdays(){
        for(Birthday b: bdays){
            System.out.println(b);
        }
    }
}

4 Comments

the obvious problem is you're creating an endless loop. Why would you print the array after each birthday? Just print the contents of the list after adding the last one.
@Stultuske read the question and answer again, please. He needs to print ALL BDays in the list for the moment of input. And i've shown him how to do that. And asked him to use HIS OWN logic to loop the input, not the endless loop i provided for test.
maybe you should re-read it. He states that on adding the previously added birthdays being printed are the issue he is trying to resolve
@Stultuske just run his code before commenting. or google "scope of a variable". His problem is that whenever he wants it to print the list, it prints only the first added Birthday. Check the first line of his main() method and then check getBirthdays() method to figure out why
0

Add field in the Birthday class:

private boolean printed = false;

Then on your print function:

 //This method will print a list of birthdays
   public void printBirthdays(ArrayList<Birthday> bdays) {    
      //iterate through each birthday and print out the result 
      for (Birthday bday : bdays) {
         if(!bday.isPrinted())
         {
            System.out.println(bday);
            bday.setPrinted(true);
         }
      }
   }

1 Comment

why on earth would anyone do this? the consequence would be "I'm going to iterate over every element each execution of the loop, and only treat the last one", so why not just change all of that in Systepm.out.println(bdays.get(bdays.size()-1); or, better yet, move the printBirthdays out of the loop

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.