简体   繁体   English

JAVA - 难以更新已排序 ArrayList 中对象的 object 信息

[英]JAVA - difficulty updating object information for objects in a sorted ArrayList

I'm trying to set element values for objects stored in a sorted ArrayList.我正在尝试为存储在排序的 ArrayList 中的对象设置元素值。 I'm having trouble entering and updating the desired information.我在输入和更新所需信息时遇到问题。 I'm unable to either issue or return a book.我无法发行或退还一本书。 Users are assumed to be unique and each book can only be issued to one user (who can have up to 3 books).假设用户是唯一的,每本书只能发给一个用户(最多可以有 3 本书)。 How do I fix this?我该如何解决?

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;

SortedArrayList class排序数组列表 class

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;

Book and user classes:书籍和用户类:

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;

    }
}

this is the commandline:这是命令行:

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

You had issues with equal methods for User and Book classes.您在 User 和 Book 类的方法相同时遇到了问题。 For quick fix you can add following snippets of codes:为了快速修复,您可以添加以下代码片段:

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

For User model I excluded numberOfBooks field, because this is not characteristic of user.对于User model,我排除了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());
    }
}

For Book model I excluded loanStatus , loanerFirstName , loanerSurName fields, because all these fields are not characteristics of book.对于Book model,我排除loanStatusloanerFirstNameloanerSurName字段,因为所有这些字段都不是图书的特征。

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

Suggestions:建议:

You should keep consistency and normalization between models:您应该保持模型之间的一致性和规范化:

  • Book should has link on User model as filed in class本书应具有用户 model 的链接,如 class 中所述

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

  • User should has field of books(Set books)用户应该有书籍领域(设置书籍)
public class User implements Comparable<User> {
   private String firstName;
   private String surName;
   private Set<Book> books;
}
  • And as result implementation of returnBook will be quite simple (set to null field user in Book , and remove book from Set inside of User model)结果returnBook的实现将非常简单(在Book中设置为 null 字段 user ,并从User模型中的 Set 中删除 book)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM