ジェネリックについての知識が限られていることをあらかじめお詫び申し上げます。
次のような状況があります。
クラス 1:
public class PostProcess implements Serializable {
public int order;
// Several other variables.
// Constructor setting vars
public PostProcess(){
}
/* Getters and setters for variables */
}
クラス 2:
public class Application extends PostProcess{
public int subOrder;
// Several other variables.
// Constructor setting vars
public Application(){
}
/* Getters and setters for variables */
}
クラス 3:
public class FileOperation extends PostProcess{
public int subOrder;
// Several other variables (different from class 'Application').
// Constructor setting vars
public FileOperation(){
}
/* Getters and setters for variables */
}
別のクラスで達成しようとしているのは、次のように定義された「FileOperation」オブジェクトと「Application」オブジェクトの混合を含むリストをソートすることです。
private ArrayList<? extends PostProcess> processList = new ArrayList<PostProcess>();
この並べ替えは、これら両方のオブジェクトの 2 つのフィールド、つまり「order」と「subOrder」で行う必要があります。「order」は PostProcess から継承され、「subOrder」は「Application」クラスと「FileOperation」クラスの両方で定義されています。
Generics、Comparable、Comparators、Interfaces を読んでいるうちに、物事が混乱したと思います。
私は次を使用して並べ替えを適用しようとしています:
Collections.sort(processList, new PostProcessComparator());
PostProcessComparator は次のように定義されます。
public class PostProcessComparator implements Comparator<? extends PostProcess> {
@Override
public int compare(Object p1, Object p2) {
int mainOrderCompare = p1.getOrder().compareTo(p2.getOrder());
if (mainOrderCompare != 0) {
return mainOrderCompare;
} else {
return p1.getSubOrder().compareTo(p2.getSubOrder());
}
}
}
質問:
Comparator (およびおそらくそれ以上) が間違っていることはわかっていますが、具体的な場所はわかりません。私は学ぶためにここにいます;)
- 「processList」リストを定義するのは正しい方法ではないことに気付きました。「FileOperation」または「Application」オブジェクトを List に追加しようとすると、コンパイラは「add(Application) に適したメソッドが見つかりません」(FileOperation の場合も同様) というメッセージで私を平手打ちします。ジェネリックを使用して processList 型を宣言できると誤って想定しましたか? 両方のクラスが PostProcess をスーパークラスとして持っているため、正しいはずですか?
- PostProcessComparator をクラス境界で定義することは、PostProcess をスーパークラスとして持つ (したがって同じメソッドにアクセスできる) オブジェクトのみを比較できるようにしたいので、私の目にはうまくいくはずです。
p1 と p2 の Comparator クラスの引数付きオブジェクトにアクセスするにはどうすればよいですか (引数の型を宣言する必要があるためです。
@Override public int compare(<What to put here?> p1, <And here?> p2) { }
皆さんが助けてくれることを本当に願っています!私が何か不明だった場合は、私に知らせてください。
ありがとう!
編集
NickJ と Winzu のおかげで、コンパレータと ArrayList の定義に必要な変更を加えました。
- subOrder を Application と FileOperation から親クラスに移動しました (そしてそれらを保護しました)
コンパレーターのパラメーター化を次のように再定義しました。
public class PostProcessComparator<T extends PostProcess> implements Comparator<T>
最初のコンパレータ比較に Integer.compare(p1.getOrder(), p2.getOrder()) を使用しました。
最後の課題 (コンパイラの警告) 呼び出し時:
Collections.sort(processList, new PostProcessComparator());
警告が表示されます: - [unchecked] unchecked method invocation: method sort in class Collections is applied to given types
required: List<T>,Comparator<? super T>
found: ArrayList<PostProcess>,PostProcessComparator
オブジェクトタイプをチェックしていないという事実を除けば、私の目にはこのコンパレーターのパラメーター化は正しいです。
これはどこが間違っていますか?