【问题标题】:How do I make a generic list in Java?如何在 Java 中制作通用列表?
【发布时间】:2012-08-27 23:00:48
【问题描述】:

我希望重新发明轮子,并在 Java 中创建自己的通用数组支持列表类,类似于 ArrayList。是的,我知道这很愚蠢,但这是一种学术追求。问题是你不能实例化一个泛型类型的数组

public class MySuperCoolList<E> {
   E[] array;

   public MySuperCoolList<E> () {
      array = new E[10]; // ERROR: cannot do this!
   }
}

这个问题肯定有解决方案,因为 Java 的 ArrayList 也在做同样的事情。问题是,怎么做?如何实例化泛型类型E 的数组?以及它是如何在 ArrayList 中完成的(如果有人知道的话)?

【问题讨论】:

  • ArrayList 在内部将其元素保存在 Objects (Object[]) 的数组中。不可能(在事先不知道类型的情况下)创建泛型数组。
  • 你可能有 C# 背景?

标签: java arrays generics arraylist


【解决方案1】:

在 ArrayList 中是如何完成的(如果有人知道的话)?

它是开源的。看看source code for ArrayList

/**
 * The array buffer into which the elements of the ArrayList are stored.
 * The capacity of the ArrayList is the length of this array buffer.
 */
private transient Object[] elementData;

【讨论】:

  • 哦,我没有意识到它是开源的。干得好!所以在泛型下面是一堆铸造是吗?好开心。谢谢!
  • @mtmurdock - Java 标准库源代码从第一天起就免费提供。早在 Java 开源之前。
  • @mtmurdock 是的,这就是所有 Java 泛型——编译时检查,然后是一堆强制转换。如果您想了解更多,关键字是“擦除”。
【解决方案2】:

在这种情况下,您可能想使用对象类型数组,因为对象类型可以容纳一切,代码如下,

public class MySuperCoolList<E> {
    Object[] array;

    public MySuperCoolList () {
       array = new Object[10];
    }

    public E get(int index){
       return (E) array[index];
    }

    public void put(int index,E val) {
      array[index] = val;
    }

}

【讨论】:

    【解决方案3】:
    public MySuperCoolList<E>(final Class<? extends E> type) {
      array = (E[]) Arrays.newInstance(type, 10);
    }
    

    Arrays.newInstance。这就是Arrays.copyOf 的工作原理。

    我已经放置了一个 PoC here

    int[] vals = (int[]) Array.newInstance(Integer.TYPE, 10);
    vals[0] = 500;
    System.out.println(vals);
    System.out.println(vals.length);
    System.out.println(Arrays.toString(vals));
    

    如你所见,输出如预期:

    [I@fb53f6
    10
    [500, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    

    【讨论】:

    • 这样的问题是消费者必须将类作为参数传递,这将是多余的。我正在尝试制作一个像 ArrayList 一样工作的集合。
    • 冗余?我真的不这么认为。
    • 你不觉得在构造函数中必须两次进入类是多余的吗?干我的朋友,干。
    • @mtmurdock 使用工厂方法,让编译器推断泛型类型参数。
    • 在运行时无法获取泛型类型的类,这意味着在某些时候仍然需要输入两次类信息。是的,您的解决方案是功能性的,但您会注意到没有一个内置类这样做,即:ArrayList
    猜你喜欢
    • 2011-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    • 2014-11-07
    • 2017-03-19
    • 2014-06-25
    • 2017-01-17
    相关资源
    最近更新 更多