Search code examples
javalistarraylistio

Trying to populate two Lists with names and ages entered by the user, and then print them into the Console


So, I'm trying to make an "Unlimited" Array List of names and ages that the user inputs, specifically when they're asked if they want to enter another name and age, and say "yes". However, I'm able to only get the name and age that's been inputted the most recently by the user.

I'm trying to have the program the names and ages to the Console when the user says "no" to inputting another name and age. However, it will print the name and age before I even it an answer to that question.

I'll post the code in question below.

    String add;
    String answer;

    ArrayList<String> names = new ArrayList<>();
    ArrayList<int[]> ages = new ArrayList<>();

    do      
    {
        // Get the users name
        System.out.println("What's your name? ");
        name = keyboard.nextLine();
        
        // Get the users name
        System.out.println("What's your age? ");
        age = keyboard.nextInt();

       // Adds the names and ages from the user input into the Arrays
        names.add(name);
        ages.add(age);
        
        // Ask the user if they want to enter in another record
        System.out.println("Do you want to enter an additional record? ");
        answer = keyboard.nextLine();
    }
    
    while (answer.equals("yes"));

    do
    {
        // System.out.println(name);
        // System.out.println(age);
        /* System.out.println(Arrays.asList(print) + ", " + (ages));
         // Printing the records to different lines of the console
           System.out.println("");
        */
    for (String print : names)
        {
            // System.out.println(names);
            // System.out.println(ages);
              System.out.println(print + ", " + (ages)); 
             
            // Printing the records to different lines of the console
              System.out.println("");
              break;
        }   
    }
    while (answer.equals("no"));

Also, I'm asking the user if they want to write the name and age Arrays to a file. Yes means write to the file, no means I write a message that says "Thanks for playing". However, depending on where I the following if I type in "yes" or "no", it will either not give the file prompt, or goes into an infinite loop with the names and ages printed, depending on where I put it.

String answer2;
String write;
String fileName;

ArrayList<String> names = new ArrayList<>();
ArrayList<String> ages = new ArrayList<>();


// If I put it here, it will do a infinite loop of the names and ages inputted.
// Prompt the user if they want to write to a file.
System.out.println("Do you want to write to a file? ");
answer2 = keyboard.nextLine();

do
{
 // If I put it here, it will continue to ask me the question infinitely.
          // Prompt the user if they want to write to a file.
          // System.out.println("Do you want to write to a file? ");
          //answer2 = keyboard.nextLine();
}
while (answer.equals("no"));

do
{
    // Prompt for the filename
    System.out.println("Enter your filename: ");
    fileName = keyboard.nextLine();
    //break;
    
    //PrintWriter outputFile;
    try 
    {
        PrintWriter outputFile = new PrintWriter(fileName);
        
        // Write the name(s) and age(s) to the file
        outputFile.println(names);
        outputFile.println(ages);
        
        outputFile.close();
    } 
    
    catch (FileNotFoundException e) 
    {
        // 
        e.printStackTrace();
        break;
    }
}   

while (answer2.equals("yes"));

do
{
    System.out.println("Thanks for playing!");
    break;
}

while (answer2.equals("no"));
keyboard.close();

Solution

  • Don't store two lists of names and ages separately, it makes your solution very brittle. Use the power of objects instead.

    Properties name and age has to associated not via indices of lists but has to be combined into an object.

    Now you have two attributes of the user. And you have to modify both list simultaneously while adding or removing user. And what if you decide that you need the third and the fourth user property? Adding more lists is not an option. User must be an object.

    With Java 16 a special kind of class call record was introduced in the language. Records are transparent carriers of data with a very concise syntax, to define a record with two properties name and age you need only this line:

    public record User(String name, int age) {}
    

    That is the equivalent of a class with a constructor, getter, equals/hasCode and toString() (all this code will be generated by the compiler for you).

    In order to organize the code nicer, I suggest you to extract the functionality for adding a user and printing the user list into separate methods.

    public class UserManager {
        
        public record User(String name, int age) {}
        
        public Scanner keyboard = new Scanner(System.in);
        public List<User> users = new ArrayList<>();
        
        public void startMainMenu() {
            System.out.println("""
                    To add a new record enter N
                    To print existing records enter P
                    To exit enter Q""");
        
            boolean quit = false;
            while (!quit) {
                String command = keyboard.nextLine().toUpperCase();
                switch(command.charAt(0)) {
                    case 'N' -> addNewUser();
                    case 'P' -> print();
                    case 'Q' -> quit = true;
                }
            }
        }
        
        public void addNewUser() {
            String answer = "no";
            do {
                System.out.println("What's your name? ");
                String name = keyboard.nextLine(); // Get the users name
                
                System.out.println("What's your age? ");
                int age = keyboard.nextInt(); // Adds the names and ages from the user input into the Arrays
                keyboard.nextLine();
                
                users.add(new User(name, age));
                
                // Ask the user if they want to enter in another record
                System.out.println("Do you want to enter an additional record? ");
                answer = keyboard.nextLine();
                
            } while (answer.equalsIgnoreCase("yes"));
            
            System.out.println("--- Main menu --- enter N, P or Q");
        }
        
        public void print() {
            for (User user: users) System.out.println(user);
            System.out.println("--- Main menu --- enter N, P or Q");
        }
    }
    

    main() - demo

    public static void main(String[] args) {
        UserManager userManager = new UserManager();
        userManager.startMainMenu();
    }
    

    Writing to a file

    public static void writeToFile(List<String> names, List<String> ages) {
        // Prompt for the filename
        System.out.println("Enter your filename: ");
        String fileName = keyboard.nextLine();
        
        try(PrintWriter outputFile = new PrintWriter(fileName)) {
            for (int i = 0; i < names.size(); i++) {
                outputFile.println("name: " + names.get(i) + ", age: " + ages.get(i));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }