Коллекции и списки в Java. Использование типизированного и неипизированного итератора

Рейтинг: -5Ответов: 1Опубликовано: 07.05.2023

Дано 3 класса:

База данных о кино - содержит список фильмов и актеров.
Фильм - список актеров, которые в нем играют.
Актер - список фильмов в которых играл.

Необходимо:

  1. (сделано) Найти актера, который не играл ни в одном фильме, используя типизированный итератор.
  2. Составить список актеров, с которыми в одном фильме играл данный актер. - тизированный цикл for-each.
  3. Найти фильм с наибольшим количеством актеров. - нетипизированный итератор.

Main.java:

import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;

 public class Main {
    public static void main(String[] args) {
        Film film1 = new Film("Harry Potter");
        Film film2 = new Film("Split");
        Film film3 = new Film("Victor Frankenstein");

        Actor actor1 = new Actor("Daniel Redcliff");
        Actor actor2 = new Actor("Emma Watson");
        Actor actor3 = new Actor("James McAvoy");
        Actor actor4 = new Actor("BattleField Overwatch");

        Database.addFilm(film1);
        Database.addFilm(film2);
        Database.addFilm(film3);
        Database.addActor(actor1);
        Database.addActor(actor2);
        Database.addActor(actor3);
        Database.addActor(actor4);

        film1.addActor(actor1);
        film1.addActor(actor2);
        film2.addActor(actor3);
        film3.addActor(actor1);
        film3.addActor(actor3);
        actor1.addFilm(film1);
        actor1.addFilm(film3);
        actor2.addFilm(film1);
        actor3.addFilm(film2);
        actor3.addFilm(film3);
    }

    // first task realization
    private static List<Actor> notFilmed() {
        List<Actor> resultList = new ArrayList<>();

        Iterator<Actor> actorIterator = Database.getActors().iterator();
        while (actorIterator.hasNext()) {
            Actor actor = actorIterator.next();
            Iterator<Film> filmIterator = Database.getFilms().iterator();

            boolean present = false;
            while (filmIterator.hasNext()) {
                Film film = filmIterator.next();
                if (film.getActors().contains(actor)) {
                    present = true;
                    break;
                }
            }

            if (!present) {
                //System.out.println("actor: " + actor.getName());
                resultList.add(actor);
            }
        }

        return resultList;
    }

}

Database.java

import java.util.ArrayList;
import java.util.List;

public class Database {
    private static List<Film> allfilms = new ArrayList();
    public static void addFilm(Film film) {
        allfilms.add(film);
    }

    private static List<Actor> allactors = new ArrayList();
    public static void addActor(Actor actor) {
        allactors.add(actor);
    }

    public static List<Actor> getActors(){
        return allactors;
    }
    public static List<Film> getFilms(){
        return allfilms;
    }
}

Film.java:

import java.util.ArrayList;
import java.util.List;
class Film{
    private String name;
    private List<Actor> actors = new ArrayList();
    public Film(String name) {
        this.name = name;
    }
    public void addActor(Actor actor) {
        this.actors.add(actor);
    }
    public List<Actor> getActors(){
        return this.actors;
    }
    public String getName() {
        return this.name;
    }
}

Actor.java:

import java.util.ArrayList;
import java.util.List;

class Actor{
    private String name;
    private List<Film> films = new ArrayList();
    public Actor(String name) {
        this.name = name;
    }
    public void addFilm(Film film) {
        this.films.add(film);
    }
    public List<Film> getFilms(){
        return this.films;
    }
    public String getName() {
        return this.name;
    }
}

Ответы

▲ 1

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

Более того, нам ведь надо как-то сравнивать фильмы между собой по количеству актёров, поэтому нам нужен именно класс Film, а не Object, поэтому в любом случае придётся делать приведение типов.

Тем не менее, ниже привожу варианты решений в соответствии с условиями.

Первая задача:

private static List<Actor> notFilmed1() {

    List<Actor> list = new ArrayList<>();

    Iterator<Actor> iterator = Database.getActors().iterator();
    while (iterator.hasNext()) {
        Actor actor = iterator.next();
        if (actor.getFilms().size() == 0) {
            list.add(actor);
        }
    }

    return list;

}

Вторая задача:

private static Set<Actor> allActors1(Actor actor) {

    Set<Actor> set = new HashSet<>();

    for (Film film : Database.getFilms()) {
        if (film.getActors().contains(actor)) {
            set.addAll(film.getActors());
        }
    }
    set.remove(actor);

    return set;

}

Третья задача:

private static Film max1() {

    Film film = Database.getFilms().get(0);

    Iterator iterator = Database.getFilms().iterator();
    while (iterator.hasNext()) {
        Film newFilm = (Film) iterator.next();
        if (newFilm.getActors().size() > film.getActors().size()) {
            film = newFilm;
        }
    }

    return film;

}

Так как эти решения ограничены условиями задачи, они мне не очень нравятся, поэтому всё же приведу более красивые решения с использованием Stream API.

Первая задача:

private static List<Actor> notFilmed2() {

    return Database.getActors().stream()
            .filter(a -> a.getFilms().size() == 0)
            .toList();

}

Вторая задача:

private static Set<Actor> allActors2(Actor actor) {

    Set<Actor> set = Database.getFilms().stream()
            .filter(f -> f.getActors().contains(actor))
            .flatMap(f -> f.getActors().stream())
            .collect(Collectors.toSet());
    set.remove(actor);
    return set;

}

Третья задача:

private static Film max2() {

    return Database.getFilms().stream()
            .max(Comparator.comparingInt(f -> f.getActors().size()))
            .get();

}

Для решения второй задачи было использовано множество Set вместо списка для того, чтобы не дублировались актёры.