0

私は下の問題にうんざりしています。助けてください?以下のインターフェースがあります

/**
* <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();

 }

そして、私のコードには2つのリストがあります:

    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) T が型変数である
ジェネリック クラス TimeStamp の型引数がありませ
ん: T は、インターフェイス TimeStamp で宣言されたオブジェクトを拡張します

コンパイル時の警告なしで上記のメソッドを定義するにはどうすればよいですか? 私のものは何ですかvoid merge(List<TimeStamp<????>> l1, List<TimeStamp<????>> l2)???? 左に?

4

2 に答える 2

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です。

マージ後、並べ替えたいと思いますが、これはタスクの別の部分です。リストを並べ替えるには、リストに格納されているクラスがインターフェイスを実装する必要がありますComparable

したがって、次のような構造になります。

    public interface TimeStamp extends Comparable<TimeStamp> {

    }

    public interface DefaultTimeStamp extends TimeStamp {

    }

    public interface FileTimeStamp extends TimeStamp {

    }

マージして並べ替えるには、少なくともT実装する to 型を制限する必要がありますComparable<T>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 ...)を使用しますか? それがどのように機能するかを説明しています。マージのために、その後、私はそれをソートします。

于 2012-11-07T11:44:50.963 に答える
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);
    }
}
于 2012-11-07T11:40:43.557 に答える