[英]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.