我厌倦了以下问题。请帮忙? 我有一个以下界面
/**
* <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)
????在左边??
答案 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);
}
}