Jatin
Jatin

Reputation: 31754

Generic Questions. Inheritance

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

Answers (2)

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

Arham
Arham

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

Related Questions