java-难以更新排序arraylist中对象的对象信息

nwlqm0z1  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(295)

我正在尝试为存储在排序arraylist中的对象设置元素值。输入和更新所需信息时遇到问题。我既不能出书也不能还书。假设用户是唯一的,每本书只能发给一个用户(最多可以有3本书)。我该怎么解决这个问题?

import java.io.*;

import java.util.Scanner;

public class Driver {

    static Scanner sc = new Scanner(System.in);

    private static void mainMenu() {
        System.out.println("------------------------------\n"+
                "f: Finish running the program\n" +
                "b -Display on the screen the information about all the books in the library\n" +
                "u -Display on the screen the information about all the users.\n" +
                "i -Update the stored data when a book is issued to a user\n" +
                "r -Update the stored data when a user returns a book to the library\n" +
                "------------------------------\n" +
                "Type a letter and press Enter\n");
    }
    private static User readNames() {
        System.out.println("Enter the user's forename then surname," + " and press Enter");
        String firstName = sc.next();
        String surName = sc.next();
        sc.nextLine();
        return new User(firstName, surName);
    }
/*    private static User readNames() throws User.InvalidBookLimitException {
        System.out.println("Enter the user's firstname: ");
        String firstName = sc.next();
        System.out.println("Enter the user's surname: ");
        String surName = sc.next();
        sc.nextLine();                                    //TODO check this
        return new User(firstName, surName, 0);
    }*/
    private static User readUserData(User user) throws User.InvalidBookLimitException {
        User u = readNames();
        System.out.println("Enter " + user + "'s age, and press Enter");

        sc.nextLine();
        return new User(u.getFirstName(), u.getSurName(),u.getNumberOfBooks());

    }

    private static Book readBookName (){
        System.out.println("Type in the name of the book");
        String bookName = sc.nextLine();
        return new Book(bookName);

    }

    //These SortedArrayLists have been derived from the sorted arraylist class
    public static SortedArrayList<User> sortedUsers = new SortedArrayList<>();

    public static SortedArrayList<Book> sortedBooks = new SortedArrayList<>();

    public static void issueBook(Book book, User user){
        for (Book b : sortedBooks){
            if(b.equals(book)) {
                b.setLoanStatus(true);
                /*b.setLoanerNames(user);*/ b.setLoanerNames("",""); //this is set temporarily like this as I can't work out how to pass in the user-entered names.
                break;
            } else {
                System.out.println("Input does not match records");
            }
        }
        for (User u: sortedUsers){
            if(u.equals(user)){
                u.setNumberOfBooks(u.getNumberOfBooks()+1);
                break;

            }
        }
    }

    public static void returnBook(Book book, User user){
        for (Book b : sortedBooks){
            if(b.equals(book)){
                 b.setLoanStatus(false);
                 b.setLoanerNames(null, null);
                break;
            } else {
                System.out.println("Input does not match records");
            }
            for (User u: sortedUsers){
                if(u.equals(user)){

                    u.setNumberOfBooks(u.getNumberOfBooks()-1);

                } else {
                    System.out.println("Input does not match records");
                }
            }
        }
    }

    public static <E> void main(String[] args) throws FileNotFoundException, User.InvalidBookLimitException {

        Book bookTest = new Book ("testbook", "ken", true, "John","Doe");
        sortedBooks.insert(bookTest);
        User test = new User ("John","Doe",2);
        sortedUsers.insert(test);

        //The inFile code uses the scanner class and it's methods to read in from the text file
        Scanner inFile = new Scanner(new FileReader("C:\\Users\\finla\\IdeaProjects\\Untitled1\\src\\books.txt"));

        try {
            FileWriter fileWriter= new FileWriter("C:\\Users\\finla\\IdeaProjects\\Untitled1\\src\\output.txt",true);
        } catch (IOException e) {
            e.printStackTrace();
        }

        //The first line of the txt file contains the number of books/corresponding authors
        //this number dictates the number of times the for loop occurs.

        int numberOfBooks = inFile.nextInt();
        inFile.nextLine(); //this line was necessary since the tally sum of nextInt() did
                           //not carry over to nextLine(), so it was necessary to blank read the integer
                           //before the for loop.

        for (int i= 0; i < numberOfBooks; i++){

            //this for loop enables reading in of the book title and author sequentially
            //until the number of books is reached.

            String bookName =  inFile.nextLine();
            /*System.out.println("Book name: " + nameBook);*/
            String authorName = inFile.nextLine();
            /*System.out.println("Book author: " + nameAuthor);*/
            Book newBook = new Book(bookName, authorName, false, null, null);

            sortedBooks.insert(newBook);

        }

        int numberOfUsers = inFile.nextInt(); //similarly, this nextInt() tells us the duration of the for loop for user's names
        inFile.nextLine();
        for (int i= 0; i < numberOfUsers; i++){
            String firstName =  inFile.next();
            /*System.out.println("First " + firstName);*/
            String lastName =  inFile.next();
           /* System.out.println("last name: " + lastName);*/

            User newUser = new User(firstName, lastName, 0);

            sortedUsers.insert(newUser);

        }

        mainMenu(); //main menu printing method
        char ch = sc.next().charAt(0);
        sc.nextLine();
        while (ch !='f') //the program ends as desired if f is pressed

        { switch(ch){

            case 'b':
                System.out.println("Displaying information about all books in the library: ");
                /*for (Object item : sortedBooks) {
                    System.out.println(sortedBooks.toString());
                }*/
                System.out.println(sortedBooks/*.toString()*/);

                break;
            case 'u':
                System.out.println("Displaying information about all users");
                System.out.println(sortedUsers/*.toString()*/);
                break;

            case 'i':
                System.out.println("Enter the loaning out data. ");
                /*System.out.println("Enter the user's first name and surname: ");*/
                readNames();
                readBookName();

                User user = readNames();
                Book book = readBookName();

                issueBook(book, user);
                /*if(User.userNameTest(readNames()))
                { User.setUser(readNames());}

                or maybe  if(u1.compareTo(u2) == 0)*/

                   /* Book book = readBookData(Book);
                    if (book != null)
                        Book.addBook(book);
                    else
                        System.out.println("The book already exists");*/ //TODO read book data method notes 1 p36 (details 41)

                break;
            case 'r':
                System.out.println("Please the details of the book to be returned: ");
                /*Book b = new Book("test1", "test2", true, "lol","lol2");*/

                /*returnBook(b);*/
                readNames();
                readBookName();

                User userReturn = readNames();
                Book bookReturn = readBookName();

                returnBook(bookReturn, userReturn);

                break;

            default:
                System.out.println("Invalid input, please enter f, b, i or r");

        }
        mainMenu();
        ch = sc.next().charAt(0);
            sc.nextLine();
        }

    }
}
import java.util.ArrayList;

SorterDarrayList类

public class SortedArrayList<E extends Comparable<E>> extends ArrayList<E> {

    //no need for a generic in the insert method as this has been declared in the class
    public void insert(E value) {
        if (this.size() == 0) {
            this.add(value);
            return; }
        for (int i = 0; i < this.size(); i++) {
            int comparison = value.compareTo((E) this.get(i));
            if (comparison < 0) {
                this.add(i, value);
                return; }
            if (comparison == 0) {
                return; }
        }

        this.add(value);
    }
import java.io.PrintWriter;

public class User implements Comparable<User> {
    private String firstName;
    private String surName;
    private int numberOfBooks;

    public User(){
        firstName = "";
        surName = "";
        numberOfBooks = 0;
    }

    public class InvalidBookLimitException extends Exception{
        public InvalidBookLimitException(){
            super("Invalid number of books");
        }

    }

    public User(String name1, String name2, int books) throws InvalidBookLimitException {

        this.firstName = name1;
        this.surName = name2;
        if (books>3) throw new InvalidBookLimitException ();
        this.numberOfBooks = books;
    }

    public User(String name1, String name2){
        this.firstName=name1;
        this.surName=name2;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getSurName(){
        return surName;
    }

    public int getNumberOfBooks(){
        return numberOfBooks;
    }

    public boolean borrowMoreBooks(){
        return numberOfBooks < 3;
    }

    public void setNumberOfBooks(int numberOfBooks){
        this.numberOfBooks=numberOfBooks;
    }

    public void setUser(String name1, String name2, int books){
        firstName = name1;
        surName = name2;
        numberOfBooks = books;

    }

    public boolean userNameTest (User otherUser){
        return (firstName.equals(otherUser.firstName) && surName.equals(otherUser.surName));
    }

  /*  public boolean loanAnotherBook(){
        return !(numberOfBooks<3);
        numberOfBooks++;
    }*/
    public void printName(PrintWriter f){f.println(firstName+ " " + surName);}

/*
    public void setUser(User user) {
        if (loanStatus == false){
            loanStatus = Driver.readNameInput();
            loanStatus = true;
        }
    }*/
    @Override
    public String toString(){
        return "Name: " + firstName + " " + surName + " | Number of books: " + numberOfBooks;
    }

    public int compareTo(User u) {
       /* int snCmp = surName.compareTo(u.surName);
        if (snCmp != 0)
            return snCmp;
        else{
            int fnCmp = firstName.compareTo(u.firstName);
            if (fnCmp !=0)
                return fnCmp;
        }*/

        int fnCmp = firstName.compareTo(u.firstName);
        if (fnCmp != 0) return fnCmp;
        int snCmp= surName.compareTo(u.surName);
        if (snCmp !=0) return snCmp;
        else return numberOfBooks -u.numberOfBooks;

    }

    @Override
    public boolean equals(Object obj) {
        return super.equals(obj);
    }
}
import java.sql.SQLOutput;

书本和用户类:

public class Book implements Comparable<Book>{
    public String bookName;
    public String authorName;
    public boolean loanStatus;
    public String loanerFirstName;
    public String loanerSurName;
    //if boolean loanStatus == true private string loaner name

    public Book(){
        bookName = "";
        authorName = "";
        loanStatus = false;
        loanerFirstName = null;
        loanerSurName = null;
    }

    Book(String book, String author, boolean loanStatus, String loanerFirstName, String loanerSurName) {

        this.bookName = book;
        this.authorName = author;
        this.loanStatus = loanStatus;
        this.loanerFirstName = loanerFirstName;
        this.loanerSurName = loanerSurName;
    }
    Book(String book){
        this.bookName=book;
    }

    public String getBookName(){
        return bookName;
    }
    public String getAuthorName(){
        return bookName;
    }
    public boolean getLoanStatus(){
        return loanStatus;
    }

    public String getLoanerFirstName(){
        return loanerFirstName;
    }
    public String getLoanerSurName(){
        return loanerSurName;
    }

    public void setBook(String book, String author, boolean loanStatus, String loanerFirstName, String loanerSurName){
        bookName = book;
        authorName = author;
        loanStatus = loanStatus;
        loanerFirstName = loanerFirstName;
        loanerSurName = loanerSurName;

    }

    public void setBookName(String bookName){
        this.bookName=bookName;
    }

    public void setLoanStatus(boolean loanStatus){
        this.loanStatus=loanStatus;
    }
    public void setLoanerNames(String loanerFirstName, String loanerSurName){
        this.loanerFirstName=loanerFirstName;
        this.loanerSurName=loanerSurName;
    }

 /*   public boolean nameTest (User otherUser){
        return (loanerFirstName.equals(otherUser.loanerFirstName)&& loanerSurName.equals(otherUser.loanerSurName));
    }

* /

    public String toString(){

        return "Book: " + bookName + " | Author: " + authorName + " | Loan status: " + loanStatus + " | Loaned to: " + loanerFirstName + " " + loanerSurName ;
    }

    //this may be redundant TODO
  /*  public void setLoanStatus(User user){
        loanStatus = false;

    }*/

    //This compare method allows new user objects to be compared to ones in the
 @Override       //sortedArrayList, enabling the insertion method.
    public int compareTo(Book b) {
        int bnCmp = bookName.compareTo(b.bookName);
        if (bnCmp != 0) return bnCmp;
        int anCmp= authorName.compareTo(b.authorName);
        if (anCmp !=0) return anCmp;
//        int lsCmp= loanStatus.(b.loanStatus);
//        if (lsCmp !=0) return lsCmp;
        int lrfnCmp =loanerFirstName.compareTo(b.loanerFirstName);
        if (lrfnCmp !=0) return lrfnCmp;
        int lrlnCmp =loanerSurName.compareTo(b.loanerSurName);
        if (lrlnCmp !=0) return lrlnCmp;
        else return 0;

    }
}

这是命令行:

r
Please the details of the book to be returned: 
Enter the user's forename then surname, and press Enter
John Doe
Type in the name of the book
testbook
Enter the user's forename then surname, and press Enter
John Doe
Type in the name of the book
testbook
Input does not match records
Input does not match records
//this is repeat about 20 times
------------------------------
f: Finish running the program
b -Display on the screen the information about all the books in the library
u -Display on the screen the information about all the users.
i -Update the stored data when a book is issued to a user
r -Update the stored data when a user returns a book to the library
------------------------------
Type a letter and press Enter
mzsu5hc0

mzsu5hc01#

对于user和book类,您在使用相等的方法时遇到了问题。对于快速修复,可以添加以下代码片段:

public class User implements Comparable<User> {
    private String firstName;
    private String surName;
    private int numberOfBooks;

    ...

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof User)) return false;
        User user = (User) o;
        return Objects.equals(getFirstName(), user.getFirstName()) &&
               Objects.equals(getSurName(), user.getSurName());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getFirstName(), getSurName());
    }
}

为了 User 不包括型号i numberOfBooks 字段,因为这不是用户的特征。

public class Book implements Comparable<Book> {
    public String bookName;
    public String authorName;
    public boolean loanStatus;
    public String loanerFirstName;
    public String loanerSurName;

    ...

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Book)) return false;
        Book book = (Book) o;
        return Objects.equals(getBookName(), book.getBookName()) &&
               Objects.equals(getAuthorName(), book.getAuthorName());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getBookName(), getAuthorName());
    }
}

为了 Book 不包括型号i loanStatus , loanerFirstName , loanerSurName 字段,因为所有这些字段都不是书的特征。

public class Driver {
        ...
        public static void returnBook(Book book, User user) {
            Book bookInLibrary = null;
            for (Book b : sortedBooks) {
                if (b.equals(book)) {
                    bookInLibrary = b;
                }
            }

            if(bookInLibrary == null) {
                System.out.println("Book wasn't found: " + book);
                return;
            }

            for (User u : sortedUsers) {
                if (u.equals(user)) {
                    //Operation returnBook should be atomic
                    bookInLibrary.setLoanStatus(false);
                    bookInLibrary.setLoanerNames(null, null);
                    u.setNumberOfBooks(u.getNumberOfBooks() - 1);

                    System.out.println("Book '" + book.getBookName() + "' was returned");
                    return;
                }
            }

            System.out.println("User wasn't found: " + user);
        }
        ...
    }

建议:
您应该保持模型之间的一致性和规范化:
这本书应该在类中归档的用户模型上有链接

public class Book implements Comparable<Book> {
       public String bookName;
       public String authorName;
       public boolean loanStatus;
       public User loaner;
   }

用户应具有图书字段(套图书)

public class User implements Comparable<User> {
   private String firstName;
   private String surName;
   private Set<Book> books;
}

作为实施 returnBook 将非常简单(在用户中设置为空字段 Book ,并将书本从 User (型号)

相关问题