1

我有2个类实现了这样的相同接口..

// Interface
Interface ISomething { ... }

// Class A
class A implements ISomething { ... }

// Class B
class B implements ISomething { ... }

然后在ArrayList<ISomething>我有很多A类和B类的实例。

有没有办法在不使用instanceof. 我绑定了许多方法(例如在 A 类和 B 类中创建新方法,让他们决定是否应该增加哪些计数变量保存在传递给他们的整数数组中),但它们似乎不是好的设计。

PS。对不起,我的英语和 Java 和 OO 设计方面的技能不足。如果这是一个不好的问题,请告诉我。

更新
我尝试了 visitor_pattern并且它有效(它比我之前使用的方法更易于维护)。
代码是这样的。。

// Interfaces
Interface ISomething { public void accept(ISomethingVisitor visitor); }
Interface ISomethingVisitor {
    public void visit(A a);
    public void visit(B b);
}

// Classes
class A implements ISomething {
     @Override
     public void accept(ISomethingVisitor visitor) { visitor.visit(this); }
}
class B implements ISomething {
     @Override
     public void accept(ISomethingVisitor visitor) { visitor.visit(this); }
}
class SomethingCountVisitor implements ISomethingVisitor {
     private int aCount;
     private int bCount;

     @Override
     public void visit(A a) { aCount++; }
     @Override
     public void visit(B b) { bCount++; }
     //getters for aCount, bCount
}

// Example usage
// Assuming items have many A and B instances.
ArrayList<ISomething> items = new ArrayList<ISomething>();
...
SomethingCountVisitor scVisitor = new SomethingCountVisitor();
for (ISomething item in items)
    item.accept(scVisitor);
4

5 回答 5

0

Google 的 Guava 有适合您的工具。https://code.google.com/p/guava-libraries/

ArrayList<ISomething> myList = ...
Iterable<A> iterableOfAs = Iterables.filter(myList, A.class);
int numOfAs = Iterables.size(iterableOfAs)

我强烈建议在您的项目中使用 Guava。它可以将您的效率提高几个数量级。对于基于 jar 的项目或 maven 管理的项目,将其添加到您的项目中都很简单。

于 2013-07-22T09:49:38.263 回答
0

如果你总是只有两个类,在你的接口中声明一个方法:

boolean isAnA();

实现它以在类中返回 true,在类中返回Afalse B。使用它的结果来决定增加哪个计数器。

如果可能有两个以上的类,请改为返回一个枚举。

然而,这一切都是间接的。如果您真的关心它是哪个类,instanceof 是提出该问题的直接、简单的方法。

于 2013-07-22T09:49:46.090 回答
0

答案很简单,NO。因为泛型只存在于编译时,而不是运行时。它们是安全措施,添加什么,不添加什么。但是一旦编译了代码, 和 之间就没有区别ArrayListArrayList<I>

不计算 using instanceof,你无法检查那里有什么!

于 2013-07-22T09:49:52.343 回答
0

您可以使用分类相等。

class Category<T> {
    private Class<T> klazz;

    public Category(Class<T> klazz) {
        this.klazz = klazz;
    }

    @Override
    public boolean equals(Object obj) {
        return obj != null && klazz.equals(obj.getClass());
    }
}

System.out.println("#A : " + Collections.frequency(list, new Category(A.class)));
System.out.println("#B : " + Collections.frequency(list, new Category(B.class)));

(在 Java 8 中,解决方案将变得更加直接。)

于 2013-07-22T10:01:58.793 回答
0

如果您不想使用instanceof,您只能使用A.class.isInstance(Object)

于 2013-07-22T09:48:59.913 回答