Получить элементы с определенным типом generi c в списке - PullRequest
2 голосов
/ 13 февраля 2020

В настоящее время я работаю над проектом поезда, и у меня есть следующий вопрос:

Я сохраняю весь подвижной состав в списке: Чтобы лучше понять мою иерархию классов, вот упрощенный обзор наследования:

RollingStock
    Engine
        SteamEngine
        DieselEngine
        ...
    Coach
        FreightCoach
        PassengerCoach
        ...
    TrainSet

В моем реестре я хочу сохранить весь подвижной состав в списке private List<RollingStock> rollingStock;. Пока что я создал список для каждого типа подвижного состава (двигатели, вагоны, комплекты поездов). Однако мне нужно удалить определенный подвижной состав только с его идентификатором, и поэтому проще сохранить все в одном списке.

Как и раньше, я создал такой движок:

    public void createEngine(Engine engine) {
        this.engines.add(engine);
    }

Теперь, используя только один список, я делаю это так:

    public void createEngine(Engine engine) {
        this.rollingStocks.add(engine);
    }

Это прекрасно работает. Для метода returnEngines () я, похоже, не нашел решения:

Это было так просто, с одним списком для каждого типа подвижного состава:

    public List<Engine> returnEngines() {
        return engines;
    }

Теперь у меня есть чтобы отфильтровать все двигатели из списка подвижного состава:

    public List<Engine> returnEngines() {
        ...
        return rollingStock.???;

    }

Я мог бы добавить метод public String getType() и проверить его тип.

Не могу себе представить, что лучшего решения нет.

Как это можно сделать?

Ответы [ 2 ]

2 голосов
/ 13 февраля 2020

Поток списка, фильтр для экземпляров Engine; сопоставьте экземпляры от RollingStock до Engine (с приведением), соберите результаты в новый List. Мол,

public List<Engine> returnEngines() {
    return rollingStocks.stream().filter(x -> x instanceof Engine)
            .map(x -> (Engine) x).collect(Collectors.toList());
}
0 голосов
/ 13 февраля 2020

Ответ от Elliott Frisch совершенно верный, вот обобщенное решение, на случай, если вам также понадобится метод фильтрации вашего регистра для любого типа вашей иерархии:

public <T> List<T> returnClazz(Class<T> clazz) {
    return rollingStocks.stream()
            .filter(clazz::isInstance)
            .map(clazz::cast)
            .collect(Collectors.toList());
}

, который затем можно использовать несколькими вспомогательными методами, например

public List<TrainSet> returnTrainset() {
    return returnClazz(TrainSet.class);
}

public List<Engines> returnEngines() {
    return returnClazz(Engine.class);
}
...

или могут быть вызваны напрямую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...