Добавление нескольких авторов в ArrayList из пользовательского ввода - PullRequest
1 голос
/ 03 октября 2019

У меня есть два класса, и они оба формируют ArrayLists. У меня есть пункт меню, в котором пользователь должен иметь возможность добавить книгу (название, авторское право, ISBN, издание и АВТОР). Это работает полностью, но проблема в том, что мне нужно добавить несколько авторов, и я не могу придумать способ обойти это. Ниже приведен мой рабочий код для добавления одного автора:

public void addBook(ArrayList<Book> books, ArrayList<Author> aut) {
    Scanner scan = new Scanner(System.in);

    System.out.println("Please enter the title:");
    String title = scan.nextLine();
    System.out.println("Please enter the copyright:");
    int copy = scan.nextInt();
    System.out.println("Please enter the edition:");
    int ed = scan.nextInt();
    System.out.println("Please enter the isbn:");
    String isbn = scan.nextLine();
    scan.nextLine();
    System.out.println("Please enter the author: ");
    String authors = scan.nextLine();

    ArrayList<Author> aut = new ArrayList<>();
    String firstName = authors.split(" ")[0];
    String lastName = authors.split(" ")[1];
    Author bookAuthor = new Author(firstName, lastName);
    boolean foundAuthor = false;

    for (int i = 0; i < aut.size(); i++) {
        Author currentAuthor = aut.get(i);
        if (currentAuthor.getFirst().equalsIgnoreCase(firstName)
                && currentAuthor.getLast().equalsIgnoreCase(lastName)) {
            bookAuthor = currentAuthor;
            foundAuthor = true;
            break;
        }
    }
    if (!foundAuthor) {
        aut.add(bookAuthor);
    }
    au.add(bookAuthor);
    books.add(new Book(title, copy, ed, isbn, au));

}

Каков наилучший подход для поддержки ввода пользователем нескольких авторов?

Ответы [ 4 ]

1 голос
/ 03 октября 2019

Это будет довольно долго, но, надеюсь, это поможет вам.

Во-первых, вы должны поместить в свой класс Book метод, который будет запрашивать у авторов авторов, и добавлять любого из введенныхавторы list для этого объекта.

Вот как будет выглядеть этот класс вместе с main, предназначенным только для тестирования. Я исключил все остальные ваши поля:

public class Book {

    ArrayList<Author> authors = new ArrayList<>();

    public Book() {

    }

    public Book(String title, int copyright, int edition, String isbn, ArrayList<Author> authors) { 
        /* 
          I left these fields out of this example on purpose.
        this.title = title; 
        this.copyright = copyright; 
        this.edition = edition; 
        this.isbn = isbn; */
        this.authors = authors; 
    }

    public void promptForAuthors()
    {
        Scanner scan = new Scanner(System.in);
        String response = "Y";

        do {
            System.out.println("Please enter the author. ");
            String input = scan.nextLine();
            String [] splitAuthors = input.split(" ");

            Author author = new Author(splitAuthors[0], splitAuthors[1]);

            if (!this.authors.contains(author)) {
                this.authors.add(author);
            }

            System.out.println("Would you like you add an additional author? (Y or N) ");
            response = scan.nextLine();

        } while(response.equalsIgnoreCase("Y"));
    }

    public void printAuthors() {
        for (Author a : this.authors) {
            System.out.println(a.getFirstName() + " " + a.getLastName());
        }
    }

    public static void main(String[] args) {
        Book b = new Book(); //This will normally be the constructor that includes the ISBN, copyright, etc.
        b.promptForAuthors();
        b.printAuthors();
    }
}

Из main видно, как вы должны использовать это в своем коде addBooks. По сути, вы создаете Book из всех других полей, которые вы использовали в качестве входных данных, затем вы можете вызвать этот метод для этого объекта.

Возможно, вам понадобится изменить ваш текущий конструктор, чтобы он больше не требовал ввода list для авторов при построении, чтобы вы могли использовать его позже (вы можете просто иметь оба доступных конструктора).

promptForAuthors() будет продолжать предлагать пользователю ввести Author, пока он не нажмет что-либо кроме Y или y.

Этот метод всегда запрашивает автора как минимум один раз из-за использования цикла do-while. Одним из главных преимуществ этого в самом классе Book является то, что этот метод можно использовать в любое время, чтобы добавить больше авторов к той же книге в будущем, если это в конечном итоге потребуется.

Дополнительно, метод будет использовать .contains(), чтобы проверить, существует ли Author внутри list, и добавить Author, только если это новый Author. Для этого требуется Override из .hashCode() и .equals() в вашем Author классе, который вы можете найти тот, который я сделал ниже:

//IN THE AUTHOR CLASS PLACE THESE METHODS AND MODIFY FOR EXTRA FIELDS
@Override
public boolean equals(Object o) {

    if (o == this) return true;
    if (!(o instanceof Author)) {
        return false;
    }

    Author user = (Author) o;

    return user.firstName.equals(this.firstName) &&
           user.lastName.equals(this.lastName);
}

@Override
public int hashCode() {
    int result = 17;
    result = 31 * result + this.firstName.hashCode();
    result = 31 * result + this.lastName.hashCode();
    return result;
}

Примечание: Я включилprintAuthors() метод, так же как простой способ проверить, не были ли добавлены лишние дубликаты Authors.

Пример Запуск добавления Авторы:

Please enter the author. 
Joe Smith
Would you like you add an additional author? (Y or N) 
y
Please enter the author. 
Billy Bob
Would you like you add an additional author? (Y or N) 
n
Joe Smith
Billy Bob
1 голос
/ 03 октября 2019

Попробуйте разрешить пользователю вводить специальную строку для выхода из цикла ввода.

Заменить

String authors = scan.nextLine();

на цикл, чтобы заполнить список строк извведите

ArrayList<String> authorNames = new ArrayList<>();
System.out.println("Please enter authors. Enter DONE when you are done.");
String nextLine = scan.nextLine();
while (!nextLine.equals("DONE")) {
  authorNames.add(nextLine);
  nextLine = scan.nextLine();
}
// This doesn't prevent the user from entering zero authors. Idk if you care about that.

альтернативно, примите ввод авторов как только одну строку с некоторым разделителем и используйте String.split для этого разделителя позже.

0 голосов
/ 03 октября 2019

Я думаю, что вы работаете с неправильной коллекцией. У вас есть пара авторских. Каждый автор мог написать несколько книг. Таким образом, правильная вещь была бы Map<Author,ArrayList<Book>>. Это сделает вашу логику программирования на addBook() проще, если вы сможете использовать карту.

0 голосов
/ 03 октября 2019

1 - создать список списков. (Список другого автора списка).

2 - создать объект списка авторов.

3 - выполнить все действия, которые вы хотите выполнитьв этом списке авторов.

4 - добавить список авторов в список авторов.

5 - Для доступа к автору необходим синтаксис вроде first_list_object.get (index) .author_object_variable_or_member.

ArrayList<ArrayList<Author>> authorList = new ArrayList<>();
ArrayList<Author> au = new ArrayList<Author>();
String firstName = authors.split(" ")[0];
String lastName = authors.split(" ")[1];
Author bookAuthor = new Author(firstName, lastName);
au.add(bookAuthor);
authorList.add(au);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...