0

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();
Alexander Ivanchenko
  • 25,667
  • 5
  • 22
  • 46
Mario
  • 37
  • 6
  • 5
    You never store the input in the lists. – dunni Apr 10 '22 at 15:47
  • Hi @dunni Thanks for the advice, I appreciate it. So, should I print the variables names and ages instead of name and age, or are you saying I need to store it by using String[] names = new String []; and int [] ages = new int [];? – Mario Apr 10 '22 at 15:54
  • See this question: https://stackoverflow.com/questions/29640718/user-input-not-working-with-keyboard-nextline-and-string-java – Delta George Apr 10 '22 at 16:03

3 Answers3

2

Missing

 names.add(name);
 ages.add(age);
Chetan Ahirrao
  • 1,454
  • 11
  • 16
  • Hi @Chetan Ahirrao Oh right, I (somehow) totally forgot about that. Thank you for that; I really appreciate it. So, do you know where I should put those? I'm asking because I've tried to them in a few places, but for some reason, I'm getting an error with ages.add(age) with the .add part that says, The method add(int, String) in the type ArrayList is not applicable for the arguments (int) – Mario Apr 10 '22 at 16:00
  • Before you ask the question, "Do you want to enter an additional record" – Chetan Ahirrao Apr 10 '22 at 16:02
  • Okay, that's what I did, thanks for the advice. I'm still getting the error with the .add part that says "The method add(int, String) in the type ArrayList is not applicable for the arguments (int)", so I don't get what I'm doing wrong. That being said, do I put them right before the question, or do I put it right above the do-while loop that the question is in, if that makes sense. Also, sorry not responding sooner, I was trying to figure out what the error was, and then I had to go do stuff for a while. – Mario Apr 10 '22 at 19:57
  • @Mario *I'm still getting the error* - If your problem is still not resolved, please, [update the question](https://stackoverflow.com/posts/71818158/edit) with the **error-message** you are getting and also show all the changes you've done to the **code**. – Alexander Ivanchenko Apr 10 '22 at 20:42
  • Hi @AlexanderIvanchenko So, I'm not getting the error anymore, but I can still only print one name and age, which it still prints them out before I can answer the question about adding an additional record, and it still asks me for a filename, even when I say no. I've also updated the code. I'm sorry for not responding sooner. – Mario Apr 10 '22 at 22:40
0

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.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • Hi @Bohemian Thanks for the advice; I really appreciate it. I have to keep the String name and age up at the top because I have other parts of the code that use the name and age variables. However, I put the rest of that code (minus the String class) into that loop though. Also, I'm trying to have it to where if I insert two different names and ages, it displays both names and ages on seperate lines, if that makes sense. I'm sorry if my original post wasn't clear on that. – Mario Apr 10 '22 at 22:26
  • @Mario this code prints names and their ages on separate lines. Also, code amended to not have the problem of variable already defined. – Bohemian Apr 10 '22 at 23:21
  • I was able to get it to print properly, and I can put in as many names and ages that I want without it being overwritten. Thanks for amending your code. I was able to just take the String class part out of your original code, make some other tweaks and now it works. Now, I just need to figure out the other part of my code, which I posted in a separate question, so that it wouldn't get overwhelming. Would you mind trying to help me with that question? It's totally fine if you can't, but if you can, I'll provide the link. – Mario Apr 10 '22 at 23:32
  • Here's the link, in case you want to help: https://stackoverflow.com/questions/71820121/trying-to-get-filename-by-user-input-and-print-message-if-the-say-no-to-wanti I had to put in a seperate comment, as my other comment was too long with the link. – Mario Apr 10 '22 at 23:34
0

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();
    }
}
Alexander Ivanchenko
  • 25,667
  • 5
  • 22
  • 46
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/243798/discussion-on-answer-by-alexander-ivanchenko-trying-to-populate-two-lists-with-n). – Ryan M Apr 11 '22 at 20:33