2013-05-20 5 views
1

Цель: мне нужно создать функцию или функции для обработки различных параметров 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, пожалуйста, предоставьте мне небольшой пример того, как перебирать список с разными типами.

Заранее спасибо :)

EDIT: Различные объекты не имеют никакого отношения друг с другом, как они не проходят друг друга и они не распространяются супер класс. Блоки каждой функции генерируют 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){}; 

} 

ИЛИ

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

Основываясь на вашем ответе на мой комментарий, вы остаетесь с двумя подходами. Первым было бы попытаться придумать интерфейс, который реализует все возможные типы, которые будут переданы этому методу. Если ваш интерфейс был назван Foo можно определить метод, как что-то вроде:

public int update(List<Foo> list) 

Тогда ваш код внутри будет основываться на методах, доступных в Foo.

Если вы не можете этого сделать, вам понадобятся отдельные методы для каждого возможного типа. Вы не можете делать instanceof во время выполнения из-за Type Erasure. Основной тип, если список стирается в скомпилированном коде и поэтому не будет доступен для instanceof логики.

EDIT: Чтобы убрать немного путаницы на мой вышеприведенный ответ. Вы можете сделать 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 приведет к коду, который будет постоянно нуждаться в изменении, когда вы добавите более поддерживаемые типы.

+0

Спасибо :), но суровый представил свой ответ перед вами, поэтому я проверил его, чтобы быть ответом. – LuckyMe

0

Расширения ответа сурового-х, не вы:

public class Update 
{ 

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

} 

А потом, в своей реализации, варьируется в зависимости от поведения переданного экземпляра класса?

Смежные вопросы