Метод, принимающий значения типа List<>

82
27 февраля 2022, 06:00

Есть класс Book, который содержит поля типа String такие как Название книги, автор, издательство, тип переплета, год издательства, кол-во страниц и цена и методы, которые возвращают данные значения типа String:

class Book{
{
    id_auto_generate++;
}
private static  int     id_auto_generate;
private         int     id = id_auto_generate;
private         String  title,                                          //название книги
                        author,                                         //автор(ы)
                        publishingOffice,                               //издательство
                        bindingType;                                    //тип переплета
private         int     yearOfPublishing,                               //год издательства
                        numberOfPages,                                  //количество страниц
                        price;                                          //цена
public int getId(){
    return this.id;
}
public String getAuthor(){
    return this.author;
}
public String getPublishingOffice(){
    return this.publishingOffice;
}
public int getYearOfPublishing(){
    return this.yearOfPublishing;
}
public String toString(){
    return String.format("ID: %03d | Название книги: %17s | Автор(ы): %14s | Издательство: %14s | Тип переплета: %17s | Год издательства: %5d | Кол-во страниц: %5d | Цена ($): %5d", id, title, author, publishingOffice, bindingType, yearOfPublishing, numberOfPages, price);
}
Book(String title, String author, String publishingOffice, String bindingType, int yearOfPublishing, int numberOfPages, int price) {
    this.title = title;
    this.author = author;
    this.publishingOffice = publishingOffice;
    this.bindingType = bindingType;
    this.yearOfPublishing = yearOfPublishing;
    this.numberOfPages = numberOfPages;
    this.price = price;
}

}

Далее есть класс 'Library', агрегирующий массив типа Book:

class Library{
    private String nameLibrary;
    private ArrayList<Book> libraryList = new ArrayList<>();
    void addBookToLibrary(Book c){
        libraryList.add(c);
    }
    //список авторов
    List<Book> getAllAuthors(){
        return new ArrayList<>(libraryList);
    }
    //список книг заданного автора
    void getBookByAuthor(String author){
        for(Book b : libraryList)
            if(b.getAuthor() == author) System.out.println(b);
    }
    //список книг заданного издательства
    void getBookByPublishingOffice(String publishingOffice){
        for(Book b : libraryList)
            if(b.getPublishingOffice() == publishingOffice)     System.out.println(b);
    }
    Library(String nameLibrary){
        this.nameLibrary = nameLibrary;
    }
}

Далее, мне нужно вывести список книг определенного автора и список книг определенной редакции, делаю я это так:

public class Main{
    public static void main(String[] args) {
        int     qt = 0;
        //создаем библиотеку
        Library lib = new Library("Gold Library");
        //добавляем книги (много книг, пишу тут только две)
        lib.addBookToLibrary(new Book("Первая книга", "Петров В.В.", "Медиа-Групп", "Интегральный", 2019, 400, 300));
    lib.addBookToLibrary(new Book("Вторая книга", "Иванов В.В.", "Цельсий", "7Б", 2018, 400, 299));

        //ВОТ ЭТОТ КОД НИЖЕ ПОВТОРЯЕТСЯ (1) и (2)
        // (1)найти всех авторов, а если авторы повторяются, узнать сколько раз повторяется автор, столько книг у его и будет
        List<Book> getAllAuthor = lib.getAllAuthors();
        System.out.println("Всего книг в библиотеке: " + getAllAuthor.size());
        System.out.println("Список доступных авторов:");
        for(int i = 0; i < getAllAuthor.size(); i++){
                    qt = 1;         //кол-во книг автора (по умолчанию значение равно 1, т.к. одна книга автора уже имеется в любом случае)
                    for(int j = i+1; j < getAllAuthor.size(); j++){
                        //проверяем по порядку, если автор следующей книги равен текущему, то его удаляем из List, но увеличиваем qt, чтобы знать, сколько у его книг
                        if(getAllAuthor.get(i).getAuthor() == getAllAuthor.get(j).getAuthor()) {
                            qt++;
                            getAllAuthor.remove(j);
                            j--;
                        }
                    }
                    System.out.println("(" + (i) + ") " + getAllAuthor.get(i).getAuthor() + " (кол-во книг данного автора - " + qt + ")");
                }
          //(2) найти издательства
          List<Book> getAllBooks = lib.getAllAuthors();
          for(int i = 0; i < getAllBooks.size(); i++){
                    qt = 1;         //кол-во книг автора (по умолчанию значение равно 1, т.к. одна книга автора уже имеется в любом случае)
                    for(int j = i+1; j < getAllBooks.size(); j++){
                        //проверяем по порядку, если издательство следующей книги равно текущему, то его удаляем из List, но увеличиваем qt, чтобы знать, сколько книг издательтва
                        if(getAllBooks.get(i).getPublishingOffice() == getAllBooks.get(j).getPublishingOffice()) {
                            qt++;
                            getAllBooks.remove(j);
                            j--;
                        }
                    }
                    System.out.println("(" + (i) + ") " + getAllBooks.get(i).getPublishingOffice() + " (кол-во книг данного издательства - " + qt + ")");
                }
    }
}

Вопрос: как создать правильно отдельный метод в классе Main или в классе Library, который в качестве аргумента будет принимать значение, по которому можно будет понять, что искать, либо авторов либо издательства. И потом этот метод вставить в класс Main типа так:

тип_возвращаемого_значения getInformationAbout(Library lib, AUTHOR){
    //два цикла for, которые будут искать всех авторов, а те авторы, которые повторяются, будет считать сколько раз повторяется
}

и

тип_возвращаемого_значения getInformationAbout(Library lib, PUBLISHINGOFFICE){
    //два цикла for, которые будут искать издательства
}
Answer 1

Не совсем понятно, как Вы собрались делать тип возвращаемого значения void...

List<Book> getAllAuthors(){
    List<Book> lb = new ArrayList<>();
    for(Book b : libraryList) lb.add(b);
    return lb;
}

Данный метод (в котором у вас отсутствуют фигурные скобки после цикла; что является плохой практикой написания код) переписывается куда короче:

List<Book> getAllAuthors(){
    return new ArrayList<>(libraryList);
}

Ну и сформулируйте вопрос более конкретно; из вашего текущего вообще не понятно - что и для чего вам нужно возвращать

Answer 2
  1. Этот метод можно сократить до return new ArrayList<>(libraryList);
  2. Вы создаете экземпляр интерфейса List с дженериком Book, в который помещаете ссылку на ArrayList с дженериком Book.

По коду: Вы можете использовать функциональный интерфейс Function<Book, V> в качестве аргумента. Тогда код примет следующий вид:

public static void main(String[] args) {
    List<Book> books = Arrays.asList(new Book("a", "1"), new Book("b", "1"), new Book("c", "2"), new Book("d", "1"));
    getInformation(new Library("Russian", books),
                             Book::getAuthor,
                             (String v, Integer n) -> "В данной библиотеке есть " + n + " книг(а)(и) автора " + v); 
}
public static<V> void getInformation(Library library, Function<Book, V> getControl, speechUses2Vars<V, Integer> speechAboutControl) {
    List<Book> booksFromLibrary = library.getBooks();
    Map<V, Integer> controls = new HashMap();
    booksFromLibrary.forEach(a -> {
        controls.put(getControl.apply(a), controls.getOrDefault(getControl.apply(a), 0) + 1);
    });
    for(Map.Entry<V, Integer> entry : controls.entrySet()) {
        System.out.println(speechAboutControl.getSpeech(entry.getKey(), entry.getValue()));
    }
}
@FunctionalInterface
interface  speechUses2Vars<T, V>{
    String getSpeech(T t, V v);
}

Вывод:

В данной библиотеке есть 3 книг(а)(и) автора 1
В данной библиотеке есть 1 книг(а)(и) автора 2

Если вам нужно сказать "В библиотеке libraryname ...", то просто добавьте еще один параметр в функцию функционального интерфейса.

READ ALSO
Как читать wss:// поток в php без библиотек (streaming api vk)

Как читать wss:// поток в php без библиотек (streaming api vk)

Streaming api vk позволяет получать события со всего вк, и реализовано это через wss:// протоколНасколько я нагуглил, wss:// не поддерживается PHP по умолчанию

93
switch &lt; или &gt; в (int)

switch < или > в (int)

Возможно ли в switch сделать проверку на < ( больше ) или > ( меньше )

171
RestAPI - как реализовать возврат данных?

RestAPI - как реализовать возврат данных?

В общем делаю проект на Laravel с RestApi и vuejsВозврат products делаю с использованием ApiResource в Laravel

76
работа с массивом через foreach

работа с массивом через foreach

Стоит задача вывести из БД таблицу с заголовкомДля отображения заголовка использую foreach, но если использовать такой код:

77