簡體   English   中英

具有通用列表參數的功能? (重載功能)

[英]Function with generic list parameter? (Overloading function)

目標:我需要創建一個或多個函數來處理不同類型的List參數,而我將遍歷該函數中的列表。

嘗試:

1-具有不同類型列表的多種功能

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

但是由於具有相同參數類型List多個函數,該代碼被認為無法編譯。

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並且不確定它的性能和成本,所以我嘗試自己做一個。 現在這是一種可怕的方式嗎?

你能做這樣的事情:

public class Update<T>
{

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

}

要么

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;
        }

現在,IMO更好的方法是通過標記界面指定要更新的類,然后干凈地處理每個類中的更新:

    interface Updateable {
        int update();
    }

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

根據您對我評論的回答,您有兩種方法。 第一個方法是嘗試提出一個接口,該接口將傳遞給此方法實現的所有可能的類型。 如果您的界面名為Foo,則可以將方法定義為:

public int update(List<Foo> list)

然后,您的代碼將基於Foo中可用的方法。

如果您無法執行此操作,則每種可能的類型都需要單獨的方法。 由於類型清除,您無法在運行時執行instanceof。 如果列表在編譯后的代碼中被擦除了,則基礎類型將無法用於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方法將導致在添加更多受支持的類型時不斷需要修改代碼。

擴大苛刻的答案,您不能這樣做:

public class Update
{

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

}

然后,在您的實現中,根據傳遞的Class實例改變行為?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM