为数据结构定义通用/变量类型

时间:2013-03-19 16:28:02

标签: java generics type-conversion

我有一个数据结构(LinkedHashMap),但问题是(第二个)值应该是变量类型,因为我可以放置类型String或类型int或任何原始类型所以我的问题是:

有没有办法为它定义一个可以获得任何值类型的变量类型?

这就是我所拥有的:

private LinkedHashMap<String, String> keyVal;

我想要这样的事情:

private LinkedHashMap<String, anyValue> keyVal;

7 个答案:

答案 0 :(得分:2)

private LinkedHashMap<String, Object> keyVal;

您可以使用Object。但请记住,在尝试从此映射中获取数据时(稍后某个时间),您可能难以将Object转换为所需的数据类型,因为您可能不知道,实际存在哪种数据类型。 / p>

因此,建议以避免此类实施。

答案 1 :(得分:1)

您不能将泛型类型作为基本类型。如果您希望能够在地图中存储任何内容,则可以将地图的“值”泛型类型设为Object

private LinkedHashMap<String, Object> keyVal;

由于自动装箱,你仍然可以存储看起来像原始类型的东西,即

keyVal.put("one", 1);
即使您指定了Integer

也会放置int

答案 2 :(得分:1)

不,你最接近的是Object作为第二个参数。

现在,我建议重新考虑你需要完成的事情,因为这实际上是反对创建的泛型。

如果您有绑定类型并希望保持一定的灵活性,那么您可以使用类似<String, ? extends SomeType>的内容。

在Java中不建议在相同的数据结构中混合使用几种类型的对象(如果这是好的或坏的,除此之外),但类型安全在防止沿线的奇怪错误方面有很长的路要走。

当你实际上需要来检索对象时,试着想一想如何处理这个问题......你会认为它们是字符串吗?你打算怎么处理他们?

答案 3 :(得分:1)

你说你想要一张地图&lt;字符串,原始类型&gt;。

the 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 isn't a primitive

您必须将以下private short sValue;添加到Any类:

private String sValue;

以及SHORT,下面的Type跟随STRING, 枚举:

{{1}}

但是,和其他人一样,最好的方法是避免使用这些弱类 (法语中的四重奏)。

答案 4 :(得分:1)

您可以使用

private LinkedHashMap<String, Object> keyVal;

将第二种类型的参数保留为尽可能通用。 它允许您将任何对象存储为值,因为每个类都扩展Object

这会让您产生一个问题,即您不知道地图中的内容类型 - 您只知道它们属于Object类型,这意味着您不知道任何内容。< / em>的

因此,要再次使用这些对象,您必须将它们转换回原始类型,这可能会导致运行时异常:ClassCastException

Generics是关于使用相同的代码定义不同类型的数据结构,但是如果要使用泛型类,则必须使用其类型参数对其进行参数化。这确保了类型在运行时是已知的并且是泛型的巨大优势(避免ClassCastException)。 但是,您仍然可以指定允许多种类型的更通用的类型。

例如,如果您通过以下方式定义它,则可以存储实现Serializable的任何对象。

private LinkedHashMap<String, ? extends Serializable> keyVal;

如您所见,这允许您将允许的类型限制为公共属性(即,成为更一般类型的子类)。这样,您可以将地图的值用作更一般的类的对象,因为它是您知道(并且想知道)有关objetcs的所有内容。

答案 5 :(得分:0)

  1. 最好看看: Generics lesson on Oracle.com
  2. 什么时候应该使用外卡(?),你应该使用泛型。
  3. 不建议在LinkedHashMap<String, Object> keyVal;类型中使用对象。

答案 6 :(得分: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.");
    }
}