2013-05-20 91 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實例有所不同的行爲嗎?