2

私はデータ構造 ( LinkedHashMap) を持っていますが、問題は、(2 番目の) 値が変数型でなければならないことです。型、Stringint、または任意のプリミティブ型をそこに置くことができるため、私の質問は次のとおりです。

任意の値型を取得できる変数型を定義する方法はありますか?

これは私が持っているものです:

private LinkedHashMap<String, String> keyVal;

私はこのようなものが欲しい:

private LinkedHashMap<String, anyValue> keyVal;
4

7 に答える 7

2
private LinkedHashMap<String, Object> keyVal;

そのために使えますObject。ただし、このマップからデータを取得しようとしている間 (後で)、Object必要なデータ型にキャストする際に困難に直面する可能性があることを覚えておいてください。

したがって、そのような実装は避けることをお勧めします。

于 2013-03-19T16:30:06.850 に答える
1

ジェネリック型をプリミティブ型にすることはできません。マップに何かを保存できるようにしたい場合は、マップの「値」ジェネリック型を次のようにすることができますObject

private LinkedHashMap<String, Object> keyVal;

オートボクシングにより、プリミティブ型のように見えるものを引き続き保存できます。

keyVal.put("one", 1);

Integerを指定しても、は を配置しますint

于 2013-03-19T16:30:00.177 に答える
1

使用できます

private LinkedHashMap<String, Object> keyVal;

2 番目の型引数をできるだけ一般的なままにします。すべてのクラスが拡張するため、任意のオブジェクトを値として格納できますObject

これは、マップ内にあるもののタイプがわからないという問題につながります。それらがタイプであることしか知らないため、何もObject知らないことを意味します

したがって、これらのオブジェクトを再度使用するには、それらを元の型にキャストし直す必要があり、実行時例外が発生する可能性があります: ClassCastException.

ジェネリックとは、同じコードで異なる型のデータ構造を定義することですが、ジェネリック クラスを使用する場合は、その型引数でパラメーター化する必要があります。これにより、型が実行時に認識されることが保証され、ジェネリックの大きな利点になります (回避ClassCastException)。ただし、複数の型を許可するより一般的な型を指定することはできます。

たとえば、次のように定義すると、 を実装する任意のオブジェクトを格納できますSerializable

private LinkedHashMap<String, ? extends Serializable> keyVal;

ご覧のとおり、これにより、許可される型を共通のプロパティに制限できます (つまり、より一般的な型のサブクラスになります)。そうすることで、マップの値をより一般的なクラスのオブジェクトとして使用できます。これは、objetcs について知っている (そして知りたい) すべてのものだからです。

于 2013-03-19T16:59:35.253 に答える
1

いいえ、最も近いObjectのは 2 番目の引数です。

ここで、何を達成する必要があるかを再考することをお勧めします。これは実際には、ジェネリックが作成された目的に反するからです。

バインドされた型があり、ある程度の柔軟性を維持したい場合は、 のようなものを使用できます<String, ? extends SomeType>

Java では、同じデータ構造に複数のタイプのオブジェクトを混在させることはお勧めできません (これが良いか悪いかは関係ありません)。

実際にオブジェクトを取得する必要があるときに、これをどのように処理するかを考えてみてください...それらが文字列であると思いますか? あなたはそれらをどうするつもりですか?

于 2013-03-19T16:31:34.940 に答える
1

あなたは Map< String, Primitive type > が欲しいと言います。

JLSによって指定された、プリミティブはNumericTypeまたはbooleanNumericTypeIntegralTypeまたはFloatingPointTypeです。

プリミティブではなくNumericTypeのみが必要な場合は、次を使用できますjava.lang.Number

Map< String, Number >

もう 1 つの方法は、考えられるすべての属性を保持するクラス Any を定義することです。

enum Type {
    NULL,
    INTEGER,
    SHORT,
    FLOAT,
    ...
}

class Any {
   private int   iValue;
   private short sValue;
   private float fValue;
   ...
   private Type  active = Type.NULL;

   public void setInt( int value ) {
      iValue = value;
      active = Type.INTEGER;
   }
   public void setFloat( float value ) {
      fValue = value;
      active = Type.FLOAT;
   }
   ...
   public int getInt() {
      if( type !=  Type.INTEGER ) {
         throw new ClassCastException( type.name() + " is not an integer" );
      }
      return iValue;
   }
   ...
}

がホルダーgetInt()で呼び出された場合、チェックを入れて例外をスローするのはあなた次第です。floatたとえば、C言語のようなトランスタイプなど、すべてが可能です。

編集

String も必要ですが、String はプリミティブではありません。

以下private short sValue;Anyクラスに追加する必要があります。

private String sValue;

そして以下のfollowinginfSHORT,Type列挙型に:

STRING,

しかし、他の人が言うように、最善の方法は、これらの弱いタイプ (フランス語で fourre-tout) を避けることです。

于 2013-03-19T16:39:56.697 に答える
0

一部の人が言ったように、特にジェネリック メソッドを使用している場合や、次の単純なもののように、ユーザーがどのようなデータ型になるかわからない場合は、ジェネリック変数型に Object を使用できます。

import java.util.Scanner;

public class GenericMethod {
    public static void main(String[] args) {
        System.out.println("Type something that's yours: ");

        Scanner sc = new Scanner(System.in);

        Object thing;
        thing = sc.next();
        isMine(thing);
    }

    // Generic Method
    public static <T> void isMine(T x) {
        System.out.println(x + " is mine.");
    }
}
于 2018-07-07T15:36:27.550 に答える