简体   繁体   English

获取列表中具有特定泛型类型的元素

[英]Get elements with a certain generic type in a list

I am currently working on a train project and I have following question:我目前正在做一个火车项目,我有以下问题:

I save all rolling stock in a list: To understand my class hierarchy better, here is a simplified inheritance overview:我将所有机车车辆保存在一个列表中:为了更好地理解我的类层次结构,这里是一个简化的继承概述:

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

In my register, I want to save all rolling stock in a list private List<RollingStock> rollingStock;在我的寄存器中,我想将所有机车车辆保存在一个列表private List<RollingStock> rollingStock; . . So far, I have created a list for each rolling stock type (engines, coaches, trainSets).到目前为止,我已经为每种机车车辆类型(发动机、客车、火车组)创建了一个列表。 However, I need to delete a certain rolling stock with just its ID and therefore it's easier to save everything in just one list.但是,我需要仅使用其 ID 删除某个机车车辆,因此将所有内容保存在一个列表中会更容易。

As of before, I created an engine like this:之前,我创建了一个这样的引擎:

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

Now, with just one list I do it like this:现在,只有一个列表,我这样做:

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

This works perfectly fine.这工作得很好。 For the returnEngines() method I don't seem to find a solution:对于 returnEngines() 方法,我似乎没有找到解决方案:

It was as easy as this with one list for each rolling stock type:每个机车车辆类型都有一个列表,就这么简单:

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

Now, I have to filter all engines out of the rolling stock list:现在,我必须从机车车辆列表中过滤掉所有引擎:

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

    }

I could add the method public String getType() and check for its type.我可以添加方法public String getType()并检查它的类型。

I can't imagine that there isn't a better solution.我无法想象没有更好的解决方案。

How can this be done?如何才能做到这一点?

Stream the list, filter for instances of Engine ;流式传输列表,过滤Engine实例; map the instances from RollingStock to Engine (with a cast), collect the results into a new List .将实例从RollingStock映射到Engine (使用演员表),将结果收集到一个新的List Like,喜欢,

public List<Engine> returnEngines() {
    return rollingStocks.stream().filter(x -> x instanceof Engine)
            .map(x -> (Engine) x).collect(Collectors.toList());
}

The answer from Elliott Frisch is perfectly valid, here is a generified solution, in case you need also a method to filter your register for any type of your hierarchy: Elliott Frisch 的答案是完全有效的,这是一个通用的解决方案,以防您还需要一种方法来过滤您的寄存器以适应任何类型的层次结构:

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

Which then can be used by several helper methods, eg然后可以由几种辅助方法使用,例如

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

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

or can be called directly.或者可以直接调用。

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

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