计算ArrayList中的不同类型(相同的接口)

时间:2013-07-22 09:42:38

标签: java interface arraylist

我有两个类实现相同的界面..

// Interface
Interface ISomething { ... }

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

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

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

有没有办法在不使用instanceof的情况下分别计算A类和B类的出现次数。我绑定了许多方法(例如在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);

5 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分: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 manged项目来说都很简单。

答案 2 :(得分:0)

如果您将始终只有两个类,请在界面中声明一个方法:

boolean isAnA();

实现它以在类A中返回true,在类B中返回false。使用其结果来决定要递增的计数器。

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

然而,这完全是间接的。如果你真的关心它是哪一个类,instanceof就是问这个问题的直接,简单的方法。

答案 3 :(得分:0)

答案很简单,不。因为泛型仅在编译期间存在,而不是在运行时存在。它们是安全措施,要添加的内容和不添加的内容。但是编译代码后,ArrayListArrayList<I>之间没有区别。

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

答案 4 :(得分: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中,解决方案将变得更加直接。)