2016-12-01 7 views
1

Я два списка:Проектирования единого API для двух различных типов

List<Date> list1 = new ArrayList<Date>(); 
List<WDate> list2 = new ArrayList<WDate>(); 

Я хочу, чтобы удалить некоторые объекты из этих списков. Эта функциональность присутствует в классе util.

public static List<Date> removeFromList1(List<Date> dateList) 
{ 
    Iterator<Date> dateItr = dateList.iterator(); 
    while(dateItr.hasNext()) 
    { 
     Date date = dateItr.next(); 
     if(date.compareTo(currentDate) <= 0) 
      dateItr.remove(); 
    } 

    return dateList; 
} 

public static List<WDate> removeFromList2(List<WDate> dateList) 
{ 
    Iterator<WDate> dateItr = dateList.iterator(); 
    while(dateItr.hasNext()) 
    { 
     WDate date = dateItr.next(); 
     if(date.getDate().compareTo(currentDate) <= 0) 
      dateItr.remove(); 
    } 

    return dateList; 
} 

class WDate 
{ 
    Date date; 
    Date getDate() { return date;} 
} 

Как создать единый метод полезности для обслуживания обоих списков?

+0

Вы должны знать лучше, чем задавать такой неопределенный вопрос. – shmosel

+0

Возможно, предоставите некоторую информацию о 'A' и' B' и покажите примерную реализацию ваших методов. – shmosel

+0

Вы можете использовать дженерики для типа элемента списка –

ответ

2

Вот возможное решение:

public static <T extends Comparable<T>> List<T> removeFromList(List<T> list, T current) 
{ 
    Iterator<T> itr = list.iterator(); 
    while(itr.hasNext()) 
    { 
     T elm = itr.next(); 
     if(elm.compareTo(current) <= 0) 
      itr.remove(); 
    } 

    return list; 
} 

...

class WDate implements Comparable<WDate> 
{ 
    Date date; 
    Date getDate() { return date;} 

    public WDate(Date date) { 
     this.date = date; 
    } 
    @Override 
    public int compareTo(WDate other) { 
     return date.compareTo(other.date); 
    } 
} 

UPDATE:

Если вы хотите, чтобы избежать реализации Сопоставимые интерфейса, вы можете поставить компаратору removeFromList:

public static <T> List<T> removeFromList(List<T> list, T current, 
     Comparator<T> comp) { 
    Iterator<T> itr = list.iterator(); 
    while(itr.hasNext()) 
    { 
     T elm = itr.next(); 
     if(comp.compare(elm, current) <= 0) 
      itr.remove(); 
    } 
    return list; 
} 

UPDATE 2 (для davidxxx)

public static List<Date> removeFromList1(List<Date> dateList) 
{ 
    return removeFromList(dateList, currentDate.getDate()); 
} 

public static List<WDate> removeFromList2(List<WDate> dateList) 
{ 
    return removeFromList(dateList, currentDate); 
} 
+0

Интересная идея, но она имеет некоторые ограничения. Вы предоставляете новый параметр, который изначально находится в классе утилиты. Этот параметр представляет собой фактическую дату. Добавление этого параметра делает некоторые внутренние данные видимыми для клиента. Кроме того, он заставляет клиента добавлять этот второй параметр при каждом вызове. Наконец, если это плохо используется, пользователь может предоставить другую дату, которая может быть непригодной. – davidxxx

+0

@davidxxx ОК, я вижу дополнительную гибкость в качестве преимущества. Вы всегда можете добавить вспомогательные функции, которые будут называть это. –

+0

В вашем вспомогательном методе вы должны сделать 'if else if', чтобы отправить текущую дату с подходящим типом:' Date' или 'WDate', так как вы должны вызвать метод 'compare()' с конкретным экземпляром, если вы хотите, чтобы сравнение работает. – davidxxx

1

Как вы не можете ввести общий интерфейс для двух типов Date (java.util.date быть не изменяемый), вы не можете иметь один метод, который бы безопасность предъявлен использование тонких дженериков: единый общий предок Object ...
Лично я считаю, что вы должны сохранить два метода, который является самым чистым способом с вашими ограничениями.
Почему? Я попытаюсь объяснить риски.
Если вы используете один метод, как сказано, у вас нет безопасности типа, и вы увеличите ответственность своего вспомогательного метода, так как он должен выполнить проверку типа прежде, чем сможет выполнять свои процедуры.

Например, вы можете сделать:

public static <T> List<T> removeFromList(List<T> dateList) { 

    Iterator<T> dateItr = dateList.iterator(); 

    while (dateItr.hasNext()) { 
    T date = dateItr.next(); 

    // check if null value otherwise illegalArgumentexception may be thrown 
    if (date == null) { 
     continue; 
    } 

    // check types 
    boolean isEquals = false; 
    if (date instanceof Date) { 
     if (currentDate.equals(date)) { 
     isEquals = true; 
     } 
    } 
    else if (date instanceof WDate) { 
     WDate wDate = (WDate) date; 
     if (currentDate.equals(wDate.getDate())) { 
     isEquals = true; 
     } 
    } 
    // if unexpected type, we rise an exception 
    else { 
    throw new IllegalArgumentException("type not supported=" + date.getClass()); 
    }  

    //perform removing 
    if (isEquals){ 
     dateItr.remove(); 
    } 
    } 

    return dateList; 
} 

и теперь вы вызываете метод, как это:

List<WDate> wdates = new ArrayList<>(); 
WDate wdate = new WDate(); 
wdates.add(wdate); 
removeFromList(wdates); 

Проблема заключается в том, что вы можете метод с любым типом в списке сейчас:

List<String> strings = new ArrayList<>(); 
String string = new String(); 
strings.add(string); 
removeFromList(strings); 

Таким образом, некоторые ошибки, которые могут быть обнаружены во время компиляции, будут обнаружены только во время выполнения n будет поднят IllegalArgumentException.