Java 迭代列表中的特定实例
我有一个ArrayList,它包含不同类的一些实例,我想在for循环中迭代特定类型的类(例如扩展OnRender.class的类); 我有一个正常工作的代码,但是代码违反了OO规则,导致了一些警告。 我能做到这一点吗?否则我将永远被沮丧打破 回顾我写的东西,我发现我没有很好地解释它,所以检查下面的代码来了解我的意思 代码:Java 迭代列表中的特定实例,java,class,oop,Java,Class,Oop,我有一个ArrayList,它包含不同类的一些实例,我想在for循环中迭代特定类型的类(例如扩展OnRender.class的类); 我有一个正常工作的代码,但是代码违反了OO规则,导致了一些警告。 我能做到这一点吗?否则我将永远被沮丧打破 回顾我写的东西,我发现我没有很好地解释它,所以检查下面的代码来了解我的意思 代码: public class ListenerManager{ List<Object> listeners=new ArrayList<Object&
public class ListenerManager{
List<Object> listeners=new ArrayList<Object>();
int it;
Class clazz;
public <T extends Object> T begin(Class<T> clazz){
it=-1;
this.clazz=clazz;
return next();
}
public <T extends Object> T next(){
while((++it)<listeners.size()){
if (clazz.isInstance(listeners.get(it))){
return (T)listeners.get(it);
}
}
return null;
}
public void add(Object listener){
listeners.add(listener);
}
}
ListenerManager lm=new ListenerManager();
lm.add(new OnRenderListener(){
........
});
for(OnRenderListener orl=lm.begin(OnRenderListener.class);orl!=null;orl=lm.next){
.......
}
我收到的警告:
public class ListenerManager{
List<Object> listeners=new ArrayList<Object>();
int it;
Class clazz;
public <T extends Object> T begin(Class<T> clazz){
it=-1;
this.clazz=clazz;
return next();
}
public <T extends Object> T next(){
while((++it)<listeners.size()){
if (clazz.isInstance(listeners.get(it))){
return (T)listeners.get(it);
}
}
return null;
}
public void add(Object listener){
listeners.add(listener);
}
}
ListenerManager lm=new ListenerManager();
lm.add(new OnRenderListener(){
........
});
for(OnRenderListener orl=lm.begin(OnRenderListener.class);orl!=null;orl=lm.next){
.......
}
类clazz代码>->类是原始类型。泛型类型类的引用应该参数化
return(T)listeners.get(it)代码>->类型安全:未选中从对象到T的强制转换
我不想只使用Suspecnd注释来挂起警告,我希望遵循OO规则。如果要标识特定的类或接口,请使用以下实例:
然而,这一点都不是很好。您确实希望利用语言的继承性和多态性。我的第一个想法是,您的列表应该只包含侦听器
或子类型,例如
listeners = new ArrayList<Listener>();
这也是一种选择。您可以将访问者对象传递给每个侦听器,每个侦听器将根据其类型决定要执行的操作。优点是,当您添加子类型时,您必须添加适当的方法——没有从类声明序列中省略类型的危险
Visitor v = new OnlyInterestedInOneTypeOfListener();
for (Listener l : listeners) {
l.useVisitor(v); // different subclasses will call different methods
// on the visitor. Some may be no-ops for different visitor
// implementations
}
(顺便说一句,我注意到您希望发现实现特定方法的条目。这是调用的,Java不支持它。其他语言(如Scala)也支持它)如果您想识别特定的类或接口,请使用instanceof:
然而,这一点都不是很好。您确实希望利用语言的继承性和多态性。我的第一个想法是,您的列表应该只包含侦听器
或子类型,例如
listeners = new ArrayList<Listener>();
这也是一种选择。您可以将访问者对象传递给每个侦听器,每个侦听器将根据其类型决定要执行的操作。优点是,当您添加子类型时,您必须添加适当的方法——没有从类声明序列中省略类型的危险
Visitor v = new OnlyInterestedInOneTypeOfListener();
for (Listener l : listeners) {
l.useVisitor(v); // different subclasses will call different methods
// on the visitor. Some may be no-ops for different visitor
// implementations
}
(顺便说一句,我注意到您希望发现实现特定方法的条目。这是调用的,Java不支持它。其他语言(如Scala)也支持它)您可以使用Guava的方法。它将只在您想要的子类型上迭代
for (YourType filteredElement : Iterables.filter(listeners, YourType.class)) {
doSomething(filteredElement);
}
你可以用番石榴的方法。它将只在您想要的子类型上迭代
for (YourType filteredElement : Iterables.filter(listeners, YourType.class)) {
doSomething(filteredElement);
}
您的ListenerManager
应该返回一个java迭代器,或者返回一个经过筛选的集合(或者列表
)。不要自己重建迭代器概念。特别是在manager类中设置begin
和next
会引入不必要的状态
使用Java 8,您的ListenerManager
可以轻松编写为:
public class ListenerManager {
private final List<Object> listeners = new ArrayList<Object>();
public <T> Collection<T> listenersOf(Class<T> type) {
return listeners.stream()
.filter(type::isInstance)
.map(type::cast)
.collect(Collectors.toList());
}
public void add(Object listener) {
listeners.add(listener);
}
}
您的ListenerManager
应该返回一个java迭代器,或者返回一个经过筛选的集合(或者列表
)。不要自己重建迭代器概念。特别是在manager类中设置begin
和next
会引入不必要的状态
使用Java 8,您的ListenerManager
可以轻松编写为:
public class ListenerManager {
private final List<Object> listeners = new ArrayList<Object>();
public <T> Collection<T> listenersOf(Class<T> type) {
return listeners.stream()
.filter(type::isInstance)
.map(type::cast)
.collect(Collectors.toList());
}
public void add(Object listener) {
listeners.add(listener);
}
}
这只是一种粗略的(不可编译的)方法
public interface Listener{
public boolean canHandle(Event ev);
public void handle(Event ev);
}
public class OnRenderListener implements Listener {
public boolean canHandle(Event ev){
return ev instanceOf OnRenderEvent; // or look for the classname
}
public void handle(Event ev);
}
public class KeyPressListener implements Listener {
public boolean canHandle(Event ev){
return ev instanceOf KeyPressEvent; // or look for the classname
}
public void handle(Event ev){
keyPressed(((KeyPressEvent)ev).getKey());
}
keyPressed(int key){....}
}
public class Event{}
public class KeyPressEvent extends Event{
int key;
}
public class OnRenderEvent extends Event{
//other stuff
}
//Loop to fire an event
for(Listener lis : listeners){
if(lis.canHandle(currentEvent){
lis.handle(currentEvent);
}
}
公共接口侦听器{
公共布尔canHandle(事件ev);
公共无效句柄(事件ev);
}
公共类OnRenderListener实现侦听器{
公共布尔canHandle(事件ev){
返回ev instanceOf OnRenderEvent;//或查找类名
}
公共无效句柄(事件ev);
}
公共类KeyPressListener实现监听器{
公共布尔canHandle(事件ev){
返回keypress事件的ev instanceOf;//或查找类名
}
公共无效句柄(事件ev){
按键(((按键事件)ev.getKey());
}
按键(输入键){…}
}
公共类事件{}
公共类KeyPressEvent扩展事件{
int键;
}
公共类OnRenderEvent扩展事件{
//其他东西
}
//循环以触发事件
for(侦听器lis:侦听器){
if(lis.canHandle(currentEvent){
lis.handle(currentEvent);
}
}
这只是一种粗略的(不可编译的)方法
public interface Listener{
public boolean canHandle(Event ev);
public void handle(Event ev);
}
public class OnRenderListener implements Listener {
public boolean canHandle(Event ev){
return ev instanceOf OnRenderEvent; // or look for the classname
}
public void handle(Event ev);
}
public class KeyPressListener implements Listener {
public boolean canHandle(Event ev){
return ev instanceOf KeyPressEvent; // or look for the classname
}
public void handle(Event ev){
keyPressed(((KeyPressEvent)ev).getKey());
}
keyPressed(int key){....}
}
public class Event{}
public class KeyPressEvent extends Event{
int key;
}
public class OnRenderEvent extends Event{
//other stuff
}
//Loop to fire an event
for(Listener lis : listeners){
if(lis.canHandle(currentEvent){
lis.handle(currentEvent);
}
}
公共接口侦听器{
公共布尔canHandle(事件ev);
公共无效句柄(事件ev);
}
公共类OnRenderListener实现侦听器{
公共布尔canHandle(事件ev){
返回ev instanceOf OnRenderEvent;//或查找类名
}
公共无效句柄(事件ev);
}
公共类KeyPressListener实现监听器{
公共布尔canHandle(事件ev){
返回keypress事件的ev instanceOf;//或查找类名
}
公共无效句柄(事件ev){
按键(((按键事件)ev.getKey());
}
按键(输入键){…}
}
公共类事件{}
公共类KeyPressEvent扩展事件{
int键;
}
公共类OnRenderEvent扩展事件{
//其他东西
}
//循环以触发事件
for(侦听器lis:侦听器){
if(lis.canHandle(currentEvent){
lis.handle(currentEvent);
}
}
那么所有监听器都实现的通用监听器接口呢?那么OnRenderListener实现/扩展监听器呢?@HankLapidez,我仍然需要强制转换,因为所有监听器都没有相同的方法,有使用touch(float x,float y y)方法的OnTouchListener和使用按键(int键)的OnKeyPressListener方法在循环中要触发事件吗?一般侦听器int如何