私は次のことを行うことに興味があり
ますMap<SomeObject<?>, ?>
。キーと値を追加するために2つのリストを使用することを考えました。
List<SomeObject<?>> keys;
List<?> values;
しかし、このリストにオブジェクトを追加する方法がわかりません。何か案は?
これは、@Ivanのアイデアを使用したこれの続きです
各エントリは異なる場合がありますが、キーと値のペアは同じ T でなければなりません
フィールド宣言のみを使用してこれを行うことはできません。
できることは、エントリごとにチェックを実行するゲッター/セッターを提供することです。
final Map<Class, Object> classObjectMap = new LinkedHashMap<Class, Object>();
public <T> void putMap(Class<T> tClass, T t) {
classObjectMap.put(tClass, t);
}
@SuppressWarnings("unchecked")
public <T> T getMap(Class<T> tClass) {
return (T) classObjectMap.get(tClass);
}
エントリごとに関係を定義できないため、フィールド自体はチェックを提供しません。ゲッターとセッターを使用すると、タイプが正しいことを確認でき、それらのみを使用すると、期待どおりに機能します。
選択したタイプは、それらに追加できないことを意味します。タイプに追加を許可します。型消去を使用して問題を回避できますが、これは理想的ではありません。
うまくいかないとは言いませんでしたが、さまざまな種類のオブジェクトを含むリスト (混合リスト) を作成する方法がわからないと言ったのです。
List<Object>
任意のオブジェクトを含むことができる を持つことができます。またはもっと単純にList
.
無関係な混合タイプのコレクションが良い考えになることはめったにありません。これは通常、DVO または DTO としてカスタム クラスを作成することを避けていることを意味します。
基本的にはそれを行うことができますが、少しのトリックで-キーと値のサイズがわかっているので、map.keys()とmap.values()で「toArray」メソッドを使用できます。これにより、2つの配列が得られます
class Key<T> {
}
Map<Key<?>, ?> map = new HashMap<Key<?>, Object>();
Key[] keyz = map.keySet().toArray(new Key[0]);
Object[] values = map.values().toArray(new Object[0]);
List<Key<?>> lstKey = Arrays.<Key<?>>asList(keyz);
List<?> lstVal = Arrays.asList(values);
Javaの配列は共変であり、それが可能になります。
たとえば、ジェネリック型List
にワイルドカードがあるa にオブジェクトを追加することはできません。?
これは、追加するオブジェクトがコレクションの実際の型に対して許可されているかどうかをコンパイラが確認する方法がないためです。例えば:
// A List that should only contain strings
List<?> list = new List<String>();
// This is not allowed, because the compiler only knows that 'list'
// is a List<?>; so it can't be sure here that integers are allowed in the list
list.add(123);
ワイルドカードのパラメーター化された型の参照変数を介してアクセスできる/アクセスできないメソッドとフィールドはどれですか? を参照してください。例を使ったより長い説明については、Angelika Langer の Java Generics FAQ を参照してください。