Java ArrayList中不同类型(相同接口)的计数
我有两个类实现了相同的接口,如下所示Java ArrayList中不同类型(相同接口)的计数,java,interface,arraylist,Java,Interface,Arraylist,我有两个类实现了相同的接口,如下所示 // Interface Interface ISomething { ... } // Class A class A implements ISomething { ... } // Class B class B implements ISomething { ... } // Interfaces Interface ISomething { public void accept(ISomethingVisitor visitor); } In
// Interface
Interface ISomething { ... }
// Class A
class A implements ISomething { ... }
// Class B
class B implements ISomething { ... }
// 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);
然后在ArrayList
中,我有很多A类和B类的实例
是否有一种方法可以在不使用instanceof
的情况下分别计算a类和B类的出现次数。我用了很多方法(比如在类A和类B中创建新方法,让它们决定是否应该增加传递给它们的整数数组中保留的计数变量),但它们似乎不是好的设计
对不起,我的英语很差,而且在Java和OO设计方面缺乏技巧。如果这是一个糟糕的问题,请让我知道
更新我试过了,效果很好(比我以前使用的方法更易于维护)。
代码是这样的
// Interface
Interface ISomething { ... }
// Class A
class A implements ISomething { ... }
// Class B
class B implements ISomething { ... }
// 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);
//接口
接口ISomething{public void accept(ISomethingVisitor);}
界面等距访问者{
公众访问(A);
公众访问(B);
}
//班级
A级实现了一件事{
@凌驾
公共无效接受(等距访问者){visitor.visit(this);}
}
B类实现了同样的东西{
@凌驾
公共无效接受(等距访问者){visitor.visit(this);}
}
类SomethingCountVisitor实现ISomethingVisitor{
私人帐户;
私人国际帐户;
@凌驾
公开访问(A){aCount++;}
@凌驾
公共无效访问(B){B计数++;}
//A计数的获取者,B计数
}
//示例用法
//假设项目有多个A和B实例。
ArrayList items=新建ArrayList();
...
SomethingCountVisitor scVisitor=新建SomethingCountVisitor();
用于(项目中的等轴测项目)
物品。接受(访客);
如果你不想使用instanceof
你只能使用A.class.isInstance(Object)
谷歌的番石榴为你准备了工具
ArrayList myList=。。。
Iterable iterableOfAs=Iterables.filter(myList,A.class);
int numOfAs=Iterables.size(iterableOfAs)
我强烈建议您在项目中使用番石榴。它可以在数量级上提高您的效率。无论是基于jar的项目还是maven管理的项目,将其添加到项目中都非常简单。如果始终只有两个类,请在接口中声明一个方法:
boolean isAnA();
在类A
中实现它以返回true,在类B
中返回false。使用其结果决定递增哪个计数器
如果可能有两个以上的类,则返回枚举
然而,这一切都相当间接。如果您真的关心它是哪个类,那么instanceof是问这个问题的直接、简单的方法。答案很简单,不是。因为泛型只在编译时存在,而不是在运行时存在。它们是安全措施,增加什么和不增加什么。但是,一旦编译了代码,
ArrayList
和ArrayList
之间就没有区别了
如果不使用
instanceof
进行计数,则无法检查有什么 您可以使用分类相等
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)));
类别{
私家级卡拉兹;
公共类(klazz类){
this.klazz=klazz;
}
@凌驾
公共布尔等于(对象obj){
返回obj!=null&&klazz.equals(obj.getClass());
}
}
System.out.println(“#A:+Collections.frequency(list,newcategory(A.class)));
System.out.println(“#B:+Collections.frequency(列表,新类别(B.class)));
(在Java 8中,解决方案将变得更加直接。)问题:为什么要有一个ISomething列表,同时需要计算每个子类型的Istance数?在我看来,A和B的两个列表会更好。可能不需要关心它是哪一类,但如果这是重要的,instanceof是一种简单、直接的方法。为什么要避免它呢?当添加新元素时,我希望新元素的类型无关紧要,只要它实现了一件事。这是一个糟糕的设计吗?这不是一个糟糕的设计。但是为什么你需要知道具体的类呢?因为我想计算不同的类型。当添加新元素时,我事先不知道它是哪种类型(但它总是实现ISomething),所以我不能只增加单独的计数变量。如果a和B是参数化类,而不是参数化类,那么答案将是真的。在这种情况下,这个问题是完全正确的。如果您的接口需要了解有关其实现者的任何信息,那么这就是糟糕的设计。谢谢您的建议。我试试看。