通用问题。遗产

时间:2012-11-07 11:21:13

标签: java generics

我厌倦了以下问题。请帮忙? 我有一个以下界面

/**
* <T> Type of Timestamp. For ex: Date, long, Calendar etc
* 
*/
public interface TimeStamp<T> extends Comparable<TimeStamp<T>>
{

/**
* Returns the timestamp. 
 * @return 
*/
 public T getTimeStamp();

 }

在我的代码中,我有两个列表:

    List<FileTimeStamp> f = new ArrayList<FileTimeStamp>();
    List<DefaultTimeStamp> t = new ArrayList<DefaultTimeStamp>();

我想创建一个方法,它接受包含TimeStamps的上述2个列表,然后合并它们。 例如:

void merge(List<TimeStamp> l1, List<TimeStamp> l2)
{
    l1.addAll(l2);
    Collections.sort(l1);
}

但是上面会生成编译时警告。

  

void merge(List l1,List l2)
   缺少泛型类TimeStamp的类型参数
   其中T是一个类型变量:       T扩展了在TimeStamp接口中声明的Object

如何在没有任何编译时警告的情况下定义上述方法?应该是我的void merge(List<TimeStamp<????>> l1, List<TimeStamp<????>> l2) ????在左边??

2 个答案:

答案 0 :(得分:4)

如果你关心类型安全,你必须有相同的类型。

您的问题的解决方案是:

public static <T> void  merge(List<T> left, List< ? extends T> right) {
         left.addAll(right);
}

这将如何运作:

  List<TimeStamp> timeList = new ArrayList<>();
  List<DefaultTimeStamp> defaultTimeList = new ArrayList<>();
  List<FileTimeStamp> fileTimeList = new ArrayList<>();

我们能够执行:

 merge(timeList, defaultTimeList);
 merge(timeList, fileTimeList);

 merge(timeList, timeList);
 merge(defaultTimeList, defaultTimeList);
 merge(fileTimeList, fileTimeList);

我们无法:

 merge(fileTimeList, defaultTimeList);

成功的关键是必须将right列表项分配给left列表中的项目类型。

合并后你要排序,这是任务的另一部分。要对List进行排序,列表中存储的类应该实现接口Comparable

所以我们最终得到这样的结构:

    public interface TimeStamp extends Comparable<TimeStamp> {

    }

    public interface DefaultTimeStamp extends TimeStamp {

    }

    public interface FileTimeStamp extends TimeStamp {

    }

要进行合并和排序,我们需要限制T至少在T上实现Comparable<T>的类型

看起来像这样:

public static <T extends Comparable<? super T>> void  mergeAndSort(List<T> left, List< ? extends T> right) {

    left.addAll(right);
    Collections.sort(left);
}

所以我们可以说你有你想要的东西。


但我会将操作分开并使用 Iterables.concat(Iterable ...),在Combine multiple Collections into a single logical Collection?中描述它是如何工作的;合并之后,我会对它进行排序。

答案 1 :(得分:0)

这对我有用,

public interface TimeStamp<T> extends Comparable<TimeStamp<T>> {
    public T getTimeStamp();
}
public class FileTimeStamp<T> implements TimeStamp<T>{

    @Override
    public int compareTo(TimeStamp<T> arg0) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public T getTimeStamp() {
        // TODO Auto-generated method stub
        return null;
    }

}
public class DefaultTimeStamp<T> implements TimeStamp<T>{

    @Override
    public int compareTo(TimeStamp<T> arg0) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public T getTimeStamp() {
        // TODO Auto-generated method stub
        return null;
    }

}
public class Abcd<T> {
    public static void main(String[] args) {
        List<FileTimeStamp<Date>> l1 = new ArrayList<FileTimeStamp<Date>>();
        List<DefaultTimeStamp<Long>> l2 = new ArrayList<DefaultTimeStamp<Long>>();
        Abcd abcd = new Abcd();
        abcd.merge(l1, l2);
    }

    void merge(List<TimeStamp> l1, List<TimeStamp> l2)  {
        l1.addAll(l2);
        Collections.sort(l1);
    }
}