Home > Net >  Trying to populate two Lists with names and ages entered by the user, and then print them into the C
Trying to populate two Lists with names and ages entered by the user, and then print them into the C

Time:04-12

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();

CodePudding user response:

Missing

 names.add(name);
 ages.add(age);

CodePudding user response:

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();
    }
}

CodePudding user response:

You last loop for printing should be more like:

for (int i = 0; i < names.length; i  ) {
    System.out.println(names.get(i)   " is "   ages.get(i)   " years old");
}

It's never a good idea to have a separate data structure (in this case a List) for each attribute of your objects. Rather, create a class for the object and have a single data structure (ie List) for your objects, which you create using the input.

For example:

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

Then at the top of your method:

List<Person> people = new ArrayList<>();

and in your input loop:

people.add(new Person(name, Integer.parseInt(age));

then to print:

people.forEach(System.out::println);

The print uses the default toString() implementation, but you can override it as you like.

  • Related