我有一个数据结构(LinkedHashMap
),但问题是(第二个)值应该是变量类型,因为我可以在那里放置类型String
或类型int
或任何原始类型,所以我的问题是:
有没有办法为它定义一个可以获取任何值类型的变量类型?
这就是我所拥有的:
private LinkedHashMap<String, String> keyVal;
我想要这样的东西:
private LinkedHashMap<String, anyValue> keyVal;
我有一个数据结构(LinkedHashMap
),但问题是(第二个)值应该是变量类型,因为我可以在那里放置类型String
或类型int
或任何原始类型,所以我的问题是:
有没有办法为它定义一个可以获取任何值类型的变量类型?
这就是我所拥有的:
private LinkedHashMap<String, String> keyVal;
我想要这样的东西:
private LinkedHashMap<String, anyValue> keyVal;
private LinkedHashMap<String, Object> keyVal;
你可以使用Object
它。但请记住,在尝试从该映射中取回数据时(稍后),您可能难以将其转换Object
为所需的数据类型,因为您可能不知道实际存在的数据类型。
因此,建议避免此类实现。
您不能让泛型类型成为原始类型。如果您希望能够在地图中存储任何内容,则可以将地图的“值”泛型类型设为Object
:
private LinkedHashMap<String, Object> keyVal;
由于自动装箱,您仍然可以存储看起来像原始类型的内容,即
keyVal.put("one", 1);
将放置一个Integer
,即使您指定了一个int
.
不,您可以拥有的最接近的参数是Object
第二个参数。
现在,我建议重新考虑您需要完成什么,因为这实际上与创建泛型的目的背道而驰。
如果你有一个绑定类型并且想要保持一些灵活性,那么你可以使用类似<String, ? extends SomeType>
.
在 Java 中不建议在同一个数据结构中混合多种类型的对象(无论好坏,都是题外话),但类型安全在防止奇怪的错误方面大有帮助。
试着想想当你真正需要检索对象时你会如何处理这个问题……你会假设它们是字符串吗?你打算怎么处理他们?
你说你想要一个 Map<String, Primitive type >。
A 由JLS指定,原语是NumericType或boolean
,NumericType是IntegralType或FloatingPointType。
如果您的需要不是原始的,而只是NumericType,您可以使用java.lang.Number
:
Map< String, Number >
另一种方法是定义一个 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;
并将以下内容SHORT,
放入Type
枚举中:
STRING,
但是,就像其他人所说,最好的方法是避免这些弱类型 (法语中的fourre-tout)。
您可以使用
private LinkedHashMap<String, Object> keyVal;
使第二种类型的参数尽可能通用。它允许您将任何对象存储为值,因为每个类都扩展了Object
.
这会导致您不知道地图中的事物是什么类型的问题——您只知道它们是类型Object
,这意味着您什么都不知道。
因此,要再次使用这些对象,您必须将它们转换回它们的原始类型,这可能会导致运行时异常:ClassCastException
.
泛型是关于使用相同代码为不同类型定义数据结构,但如果您想使用泛型类,则必须使用其类型参数对其进行参数化。这确保了类型在运行时是已知的,并且是泛型的巨大优势(避免ClassCastException
)。但是,您仍然可以指定允许多种类型的更通用的类型。
例如,如果您按照以下方式定义它,您可以存储任何实现Serializable
.
private LinkedHashMap<String, ? extends Serializable> keyVal;
如您所见,这允许您将允许的类型限制为公共属性(即,成为更通用类型的子类)。这样,您将地图的值用作更通用类的对象,因为它是您所知道(并且想知道)的关于对象的一切。
LinkedHashMap<String, Object> keyVal;
不建议在类型中使用 Object 。就像有些人说的,你可以使用 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.");
}
}