繁体   English   中英

遍历异构集合

[英]Looping over heterogeneous collection

示例如下:我有一个Box ,需要填充一些Thing 我只对每件东西的重量感兴趣。 另外,除了体重,我还需要正确识别正在测量的东西。 每种事物类型都有不同的ID类型。 在这种情况下,我有玩具和水果,它们分别具有ToyIdFruitId 最后,我需要能够打印事物标识符和事物权重。

问题:是否可以在不使用instanceof运算符的情况下以某种方式访问ThingId的特定方法?

class Color{}
interface ThingId {}

class FruitId implements ThingId {
    String name;    //"apple", "orange", ...
    FruitId(String name){  this.name = name; }
    String getName(){ return this.name; }
}

class ToyId implements ThingId {
    String shape;   //"square", "circle", ...
    Color color;    //"red", "blue"...
    ToyId(String shape, Color color){ this.shape = shape; this.color = color; }
    String getShape(){ return this.shape; }
    Color getColor(){ return this.color; }
}

class Thing{
    ThingId thingId;
    Integer weight;
    public Thing(ThingId thingId, Integer weight){
        this.thingId = thingId;
        this.weight = weight;
    }
    ThingId getThingId(){ return this.thingId; }
    Integer getWeight(){ return this.weight; }
}

class Box {
    Set<Thing> things = new HashSet<>();

    void addThing(Thing thing){
        this.things.add(thing);
    }

    Collection<Thing> getThings(){
        return this.things;
    }
}

class Program {
    public static void main(String[] args) {
        FruitId appleId = new FruitId("apple");
        Thing apple = new Thing(appleId, 1);
        ToyId cubeId = new ToyId("square", new Color());
        Thing cube = new Thing(cubeId, 22);

        Box box = new Box();
        box.addThing(apple);
        box.addThing(cube);

        for(Thing t : box.getThings()){
            System.out.print("Thing Id is: ");
            if(t.getThingId() instanceof FruitId) { //any other possibility than using instance of?
                process((FruitId)t.getThingId());
            }
            if(t.getThingId() instanceof ToyId){    //any other possibility than using instance of?
                process((ToyId)t.getThingId());
            }
            System.out.println("Weight is : " + t.getWeight());
        }
    }

    static void process(FruitId fruitId){
        System.out.println(fruitId.getName());
    }

    static void process(ToyId toyId){
        System.out.println(toyId.getShape() + toyId.getColor());
    }
}

更新

好的,我认为访客模式在这里可能有用:

class Color{}
interface ThingId {
    void visitThingId(ThingIdVisitor visitor);
}

class FruitId implements ThingId {
    String name;    //"apple", "orange", ...
    FruitId(String name){  this.name = name; }
    String getName(){ return this.name; }

    @Override
    public void visitThingId(ThingIdVisitor visitor) {
        visitor.process(this);
    }
}

class ToyId implements ThingId {
    String shape;   //"square", "circle", ...
    Color color;    //"red", "blue"...
    ToyId(String shape, Color color){ this.shape = shape; this.color = color; }
    String getShape(){ return this.shape; }
    Color getColor(){ return this.color; }

    @Override
    public void visitThingId(ThingIdVisitor visitor) {
        visitor.process(this);
    }
}

class Thing{
    ThingId thingId;
    Integer weight;
    public Thing(ThingId thingId, Integer weight){
        this.thingId = thingId;
        this.weight = weight;
    }
    ThingId getThingId(){ return this.thingId; }
    Integer getWeight(){ return this.weight; }
}

class Box {
    Set<Thing> things = new HashSet<>();

    void addThing(Thing thing){
        this.things.add(thing);
    }

    Collection<Thing> getThings(){
        return this.things;
    }
}

class ThingIdVisitor{
    void process(FruitId fruitId){
        System.out.println(fruitId.getName());
    }

    void process(ToyId toyId){
        System.out.println(toyId.getShape() + toyId.getColor());
    }
}

class Program {
    public static void main(String[] args) {
        FruitId appleId = new FruitId("apple");
        Thing apple = new Thing(appleId, 1);
        ToyId cubeId = new ToyId("square", new Color());
        Thing cube = new Thing(cubeId, 22);

        Box box = new Box();
        box.addThing(apple);
        box.addThing(cube);

        for(Thing t : box.getThings()){
            System.out.print("Thing Id is: ");

            t.getThingId().visitThingId(new ThingIdVisitor());

            System.out.println("Weight is : " + t.getWeight());
        }
    }
}

我真的没有得到您想要达到的目标。 首先,我没有使用ThingId接口。 其次,我认为您对接口和继承有点困惑。 如果我是你,我会查找多态性

无论如何,我建议您删除ThingId接口,并让FruitIdToyId类扩展Thing类。 由于您的集合仅存在Thing ,并且您的FruitToy类都扩展了Thing类并因此实现了getWeight()方法,因此您不应再使用instanceof

但是,请继续阅读多态性

您的界面ThingId必须提供您想要的相应方法。

如果您简单地想打印出信息,那么您可以像简单地使用

public String getInformation();

然后,实现可以返回与其相关的信息,您只需在应用程序代码中使用ThingId

顺便说一句:当您将Thing存储在HashSet确保在所有Thing实现中实现equalshashCode

我也真的看不出来,为什么需要ThingThingId ,因为ThingId似乎不仅仅是一个简单的id,而是一个实际的东西。 所以对于我来说, ThingId似乎是多余的,并且可以通过拥有不同的Thing来实现

由于您要在两种实例类型上调用相同的方法process ,因此为什么不将该方法添加到ThingId接口本身。

这样,您可以致电:

t.getThingId().process();

而不是查找实例类型并调用各自的方法。

暂无
暂无

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

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