为两种不同的类型设计单个 API
Designing single API for two different types
我有两个列表:
List<Date> list1 = new ArrayList<Date>();
List<WDate> list2 = new ArrayList<WDate>();
我想从这些列表中删除一些对象。此功能存在于 util class.
中
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;}
}
如何创建一个实用方法来为两个列表提供服务?
这是一个可能的解决方案:
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 接口,您可以为 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);
}
因为你不能为两种类型的 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);
所以一些可以在编译时检测到的错误,只有在运行时 IllegalArgumentException
被引发时才会被发现。
我有两个列表:
List<Date> list1 = new ArrayList<Date>();
List<WDate> list2 = new ArrayList<WDate>();
我想从这些列表中删除一些对象。此功能存在于 util class.
中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;}
}
如何创建一个实用方法来为两个列表提供服务?
这是一个可能的解决方案:
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 接口,您可以为 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);
}
因为你不能为两种类型的 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);
所以一些可以在编译时检测到的错误,只有在运行时 IllegalArgumentException
被引发时才会被发现。