为两种不同类型设计单个API

时间:2016-12-01 06:56:03

标签: java oop generics api-design

我有两个名单:

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

如何创建单个实用程序方法来同时提供这两个列表?

2 个答案:

答案 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);
    }
}

更新:

如果您想避免实现Comparable接口,可以提供一个Comparator来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;
}

更新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);
}

答案 1 :(得分:1)

由于你不能为两种类型的日期(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中的任何类型的方法:

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

因此,只有在IllegalArgumentException被引发时才会在运行时发现可以在编译时检测到的一些错误。