2013-05-20 34 views
1

目标:我需要的是创建一个或多个函数来处理List参数的不同类型,并且我将遍历函数中的列表。具有通用列表参数的函数? (超载函数)

尝试:用不同类型的列表

public static int update(List<MyClass> myClasses){}; 
public static int update(List<Project> rojects){}; 
public static int update(List<Time> times){}; 

由于与相同参数类型List多种功能

1-多种功能但是,这被认为是在-编译为。

2-通用类型的列表,并使用(instanceof)但是,我没有完全做到这一点,因为我不知道如何,以及像我读的那样,这似乎是这种行为的不利方式。

我的问题:实现这种需求的Java方法是什么?我需要一个干净的代码,我不在乎它是否复杂,我主要关心准确性和正确的编码。

PS:如果instanceof的方法正确,那么请您提供一个关于如何迭代不同类型列表的示例。

感谢提前:)

编辑:不同的对象有相互没有关系,如,他们不相互延伸也不扩展超类。每个函数的块都会生成一个SQLite语句,这对每种类型都是不同的。


应对“恶劣的回答是:

所以最后我用你的建议组合,那就是实现与getClassType()函数返回的类名的字符串一个基类,那么我会检查update(List<T> list)函数中的返回值。

public static <T extends Item> int update(List<T> list){ 
    ... 
    // Loop through the list and call the update function 
    for (T item: list){ 
     if (item.getClassType() == MyClass.CLASS_TYPE) 
      update((MyClass) item); 

    } 
    ... 
} 

public interface Item { 
    /** 
    * @return Return the class type, which is the name of the class 
    */ 
    public String getClassType(); 
} 

public class ClassProject implements Item{ 
    public static final String CLASS_TYPE = "ClassProject"; 
    @Override 
    public String getClassType() { 
     return CLASS_TYPE; 
    } 
    ... 
} 

public class ClassTime implements Item{ 
    public static final String CLASS_TYPE = "ClassTime"; 
    @Override 
    public String getClassType() { 
     return CLASS_TYPE; 
    } 
    ... 
} 

public class MyClass implements Item{ 
    public static final String CLASS_TYPE = "MyClass"; 
    @Override 
    public String getClassType() { 
     return CLASS_TYPE; 
    } 
    ... 
} 

这样做的理由整个interface是因为我不喜欢istanceof并不能确定它的性能和成本,所以我试图让我自己的一个。现在是这样做的一个可怕的方式?

+0

不同类型的处理块发生了什么?如果代码的类型A与类型B的列表相同,或者代码是通用的,并且不管列表中的基础类型是否更改。如果有两种可能的方法,这个答案将决定一个答案。 – cmbaxter

+0

它会根据类型完全不同。该代码将为列表中的每个项目创建一个SQLite更新语句,并针对每种类型的项目创建不同的语句。 – LuckyMe

回答

4

你能不能做这样的事情:

public class Update<T> 
{ 

public static int update(List<T> objects){}; 

} 

OR

public static <T> int update(List<T> objects){}; 

无论是在你的情况更合适。

所以,如果你的第二个办法,由于请在运行时擦除,你会留下的instanceof检查去:

public static <T> int update(List<T> objects){ 
     for(T object : objects) 
     { 
      if(object.getClass().isInstance(Pair.class)) 
      { 
       //do something 
      }else if(object.getClass().isInstance(Time.class)) 
      { 

      } 
     } 
     return 0; 
    } 

但是,这看起来并不好的设计,你可以通过使用一个以上的改善工厂方法:

static Handler getHandler(Class<?> handlerClass) 
     { 
      if(handlerClass.isInstance(Project.class)) 
      { 
       //return ProjectHandler 
      }else if(handlerClass.isInstance(Time.class)) 
      { 
       //return TimeHandler 
      } 
      //return errorHandler 
     } 
     interface Handler { 
      int handle(); 
     } 
     public static <T> int update(List<T> objects){ 
      for(T object : objects) 
      { 
       getHandler(object.getClass()).handle(); 
      } 
      return 0; 
     } 

现在一个更好的办法国际海事组织将通过标记接口指定在更新你的类,然后干净利落地处理更新的每个类的:

interface Updateable { 
     int update(); 
    } 

    public static <T extends Updateable> int update2(List<T> objects){ 
     for(T object : objects) 
     { 
      object.update(); 
     } 
     return 0; 
    } 
+0

第一,这意味着每个功能的不同类别权利?如果是,那么我不能这样做,所有的功能都需要在同一个班级内。至于第二,我假设我会然后使用'instanceof'吧?这是做到这一点的正确而有效的方式吗? – LuckyMe

+0

修改了我的回复 – harsh

+0

嘿,我在回复中添加了对原始问题的修改,非常感谢,请告诉我是否是处理此问题的好方法。 – LuckyMe

1

根据您对我评论的回答,您剩下两种方法。第一种方法是尝试创建一个接口,将所有可能的类型传递给此方法。如果您的接口被称为富,你可以将方法定义是这样的:

public int update(List<Foo> list) 

内。然后你的代码将基于Foo中可用的方法。

如果你不能这样做,那么你将需要单独的方法每个可能的类型。由于Type Erasure的原因,您无法在运行时执行instanceof。如果列表在编译的代码中被清除,则基础类型将不可用于instanceof逻辑。

编辑: 要澄清我的上述答案有点混乱。

for(Object item:list){ 
    if (item instanceof A){ 
    //do A based logic 
    } 
    else if (item instanceof B){ 
    //do B based logic 
    } 
} 

但是,您不能在运行时检查列表类型,像这样:

if (list instanceof List<A>) 

你最好的选择真的是你可以遍历列表时,这样的事情每个元素的基础上做instanceof将尝试和推广我的第一个解决方案中建议通过接口支持的类型。使用instanceof方法会导致代码随着您添加更多受支持的类型而不断需要修改。

+0

谢谢:)但苛刻的提出了他的答案在你面前,所以我检查了他的答案。 – LuckyMe

0

扩大苛刻的回答,不能你:

public class Update 
{ 

public static <T> int update(List<T> objects, Class<T> clazz){}; 

} 

,然后在您的实现,根据传入的Class实例有所不同的行为吗?