Reputation: 31754
I am tired of the below issue. please help? I have a below interface
/**
* <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();
}
And in my code I have 2 lists:
List<FileTimeStamp> f = new ArrayList<FileTimeStamp>();
List<DefaultTimeStamp> t = new ArrayList<DefaultTimeStamp>();
I want to create a method that takes the above 2 lists containing TimeStamps and then merge them. Ex:
void merge(List<TimeStamp> l1, List<TimeStamp> l2)
{
l1.addAll(l2);
Collections.sort(l1);
}
But the above generates compile time warnings.
void merge(List l1, List l2)
missing type arguments for generic class TimeStamp
where T is a type-variable: T extends Object declared in interface TimeStamp
How should I define the above method without any compile time warnings? What should be my void merge(List<TimeStamp<????>> l1, List<TimeStamp<????>> l2)
???? in left be?
Upvotes: 0
Views: 148
Reputation: 30875
If you care about type safety you must have equal types.
Solution for your question is:
public static <T> void merge(List<T> left, List< ? extends T> right) {
left.addAll(right);
}
How this will work:
List<TimeStamp> timeList = new ArrayList<>();
List<DefaultTimeStamp> defaultTimeList = new ArrayList<>();
List<FileTimeStamp> fileTimeList = new ArrayList<>();
We well be able to perform:
merge(timeList, defaultTimeList);
merge(timeList, fileTimeList);
merge(timeList, timeList);
merge(defaultTimeList, defaultTimeList);
merge(fileTimeList, fileTimeList);
We will not be able to:
merge(fileTimeList, defaultTimeList);
The key to success is that right
list item must be assignalbe to type of items in left
list.
After merge you wan to sort, this is another part of task. To sort List the class that is stored in list should implements interface Comparable
So we end up with structure like this:
public interface TimeStamp extends Comparable<TimeStamp> {
}
public interface DefaultTimeStamp extends TimeStamp {
}
public interface FileTimeStamp extends TimeStamp {
}
To merge and sort we need to limie the T
to type that implements Comparable<T>
at least on T
And this look like this:
public static <T extends Comparable<? super T>> void mergeAndSort(List<T> left, List< ? extends T> right) {
left.addAll(right);
Collections.sort(left);
}
So we can say that you have what you want.
But i would separate the operations and use Iterables.concat(Iterable ...), in Combine multiple Collections into a single logical Collection? is describe how it works; for merging and after that i would sort it.
Upvotes: 4
Reputation: 2102
This works for me,
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);
}
}
Upvotes: 0