【问题标题】:How do I print one or multiple objects from an ArrayList with a particular attribute?如何从具有特定属性的 ArrayList 中打印一个或多个对象?
【发布时间】:2021-08-22 17:06:43
【问题描述】:

我有一本书课:

public class Book {
    public String title;
  
    public  String author;

    public  int genre;
    
    public Book(){}
  
    public Book(String title, String author, int genre) {
        this.title = title;
        this.author = author;
        this.genre = genre;
    }
  

    public String getBookTitle() {
        return  title;
    }
    
    public String getBookAuthor() {
        return author;
    }
    
    public String getBookGenre() {
        if (genre == 1) {
          return ("Fantasy");
        }
        else if (genre == 2) {
          return ("Science Fiction");
        }
        else if (genre == 3) {
          return ("Dystopian");
        }
        return "genre";
        
    }

    @Override
    public String toString() {
        return ("Title: " + this.getBookTitle() + " \nAuthor: " + this.getBookAuthor() + " \nGenre: " + this.getBookGenre() + "\n");
    }
    
}

我有一个 LibraryDatabase 类,它有一个包含两个 Book 对象的 ArrayList:

import java.util.*;
public class LibraryDatabase extends Book {
  List<Book> bookDatabase = new ArrayList<>();

  public LibraryDatabase() {
      super();
  }

  public List<Book> books() {
    Book book1 = new Book("Harry Potter", "J.K. Rowling", 1);
    Book book2 = new Book("Neuromancer", "William Gibson", 2);

    bookDatabase.add(book1);
    bookDatabase.add(book2);
    return bookDatabase;
  }
}

我想让用户选择他们想要的类型,并让控制台打印出所有具有该类型作为属性的对象。 我在一个单独的类中有这个方法:

public void showTitles() {
    LibraryDatabase libraryDatabase = new LibraryDatabase();
    Scanner kbMeter = new Scanner(System.in);
    String genre = kbMeter.nextLine();
    if (genre.equals(libraryDatabase.getBookGenre())) {
      //???
    }

  }

我不知道在 if 语句中放什么才能打印出具有该类型的所有对象。感谢您的帮助。

【问题讨论】:

    标签: java oop if-statement arraylist


    【解决方案1】:

    我建议至少像这样重构books() 方法以防止引用转义

    public Collection<Book> getBooks() {
        Book book1 = new Book("Harry Potter", "J.K. Rowling", 1);
        Book book2 = new Book("Neuromancer", "William Gibson", 2);
    
        bookDatabase.add(book1);
        bookDatabase.add(book2);
        return Collections.unmodifiableCollection(bookDatabase);
    } 
    

    并重构 showTitles 方法,使其使用 java 8 功能和更通用的功能:

    public void showTitles(Consumer<Book> consumer) {
        LibraryDatabase libraryDatabase = new LibraryDatabase();
        Scanner kbMeter = new Scanner(System.in);
        String genre = kbMeter.nextLine();
        libraryDatabase.getBooks()
                    .stream()
                    .filter(b -> b.getBookGenre().equals(genre))
                    .forEach(consumer);
    
    }
    

    并像这样使用这个 API:

    LibraryDatabase db = new LibraryDatabase();
    db.showTitles(b -> System.out.println(String.format("%s, %s, %s", b.getBookAuthor(), b.getBookTitle(), b.getBookGenre())));
    

    【讨论】:

    • “像这样使用这个 API”是什么意思。我是计算机科学的新手,我不完全知道 API 是我代码的哪一部分。
    • 另外,Consumer 是从哪里来的?
    • API 我的意思是showTitles 方法。您可以将消费者传递给您的方法,以便为每本书执行所需的逻辑。这里我只打印出来,你可以在调用这个方法时提供另一个消费者做其他事情
    【解决方案2】:

    您的设计存在根本问题。您的 LibraryDatabase 不应扩展 Book

    您可以在LibraryDatabase 类中公开findBookByGenre(String genre) 方法或过滤books() 返回的列表。

            libraryDatabase.books().forEach(book -> {
                if ("aaa".equals(book.getBookGenre())) {
                    System.out.println(book.getBookTitle());
                }
            });
    
    

    【讨论】:

      【解决方案3】:

      遍历数据库中每个Book 的简单for 循环应该可以工作:

      for (Book book : bookDatabase) {
          if (book.getBookGenre().equals(genre) {
              System.out.println(book);
          }
      }
      

      【讨论】:

      • bookDatabase 运行时找不到符号。
      • @FouadSaffar 好吧,你从来没有指定 showTitles 在哪里,所以我认为它在你的 LibraryDatabase 类中。这可能就是显示该错误的原因。我认为您想要做的是将bookDatabase 替换为libraryDatabase.books()。试试看它是否有效
      • @megargayu 调用books() 可能不是最好的主意,因为showTitles 可能会被调用多次,但每次books() 调用都会将两本书添加到bookDatabase 列表中。它的代码可能应该移动到LibraryDatabase 构造函数,而不是books() 那里可以是像public List&lt;Book&gt; getAllBooks(){return new ArrayList&lt;&gt;(bookDatabase); } 这样的方法来返回所有书籍列表的副本(以防止修改原始bookDatabase)。
      • @Pshemo 是的,我并没有真正想到所有这些并发症。实际上,您可能希望完全重构此代码的工作方式,因为 LibraryDatabase 不应该扩展 BookshowTitles 可能不应该要求用户输入,而是将其作为参数获取,然后单独添加类来调用函数等。此外,使用HashMap&lt;String, Book&gt; genres 变量进行 O(1) 查找会更好
      猜你喜欢
      • 1970-01-01
      • 2020-05-08
      • 1970-01-01
      • 1970-01-01
      • 2021-05-08
      • 2015-05-23
      • 1970-01-01
      • 1970-01-01
      • 2017-01-06
      相关资源
      最近更新 更多