无法使用Java泛型将{int>类型转换为E

时间:2016-05-04 22:03:25

标签: java generics queue

在使用Java之前一直很好。我很难将此队列转换为使用可接受任何数据类型的泛型。

我不明白为什么item无法转换为intitem代表"任何"数据类型。

答案加上对泛型的一点解释会很有用,因为我还需要创建一个删除函数。

private int initialCapacity = 10;
private int size = 0;
private int[] content;

public static <E> void add(E item) {
    int size = 0;
    int[] content;

    // If we run out of space in the array
    if (size == content.length) {

        // 1) Create a new, larger array (2x)
        int[] newArray = new int[content.length * 2];

        // 2) Copy the content from the old array to the new one
        for (int c = 0; c < content.length; c++) {
            newArray[c] = content[c];
        }

        // 3) Let the old array point to the new array
        content = newArray;
    }

    //Add the item to the content of the array list
    content[size] = item;
    size++;
}

3 个答案:

答案 0 :(得分:3)

让我们从顶部开始。 E是一个类型参数,所以我们应该首先弄清楚它的范围。通常,对于队列,type参数作为整体应用于队列(而不仅仅是单个add)操作,因为我们希望队列具有一致的类型。因此,首先将您的课程声明为:

public class YourQueue<E> {
    ...
}

并从<E>的方法声明中删除add,使其成为public void add(E item)。不确定为什么你已经将它声明为静态,因为它应该添加到给定队列。

第三,如果您要使用数组存储YourQueue<E>的元素,则它不应该是整数数组,因为所有类型的对象都不能转换为整数。它应该是一个声明为E[]的数组。

答案 1 :(得分:0)

在Java中,泛型不支持基本类型。只需使用Integer代替int,对于您的应用程序,它们将大致相同。

另见:Why don't Java Generics support primitive types?

答案 2 :(得分:0)

您问题的简单答案是int是基本数据类型(或原始数据),除非将其包装为特定的包装类,否则对象不能自动转换为基本数据类型基本数据类型。在这种情况下,包装器类是Integer。根据创建队列的目标,将item转换为int不是您想要的,而是要使用可以在其中容纳item的数组,而不是int。 / p>

代码content[size] = item;表示将size的{​​{1}}单元分配给content的值。如果item不是item,则将失败。由于在编译时Integer的类型是模棱两可的,因此将失败。您可以通过用item数组替换int数组来解决此问题,因为Java中的每个类都以Object作为父级或祖先。

一个更详细的答案如下:

我认为您的问题可以这样改写:


“我为原始类型int创建了一个队列实现,但是我不确定如何使用泛型,以便队列可以使用泛型。

这是原始的整数队列实现,仅带有add方法(工作代码):

Object

这是修改后的队列实现,仅带有使用泛型的add方法:

public class IntQueue {
   private int initialCapacity = 10;
   private int size = 0;
   private int[] content = new int[initialCapacity];

   public void add(int item) {

      // If we run out of space in the array
      if (size == content.length) {

          // 1) Create a new, larger array (2x)
          int[] newArray = new int[content.length * 2];

          // 2) Copy the content from the old array to the new one
          for (int c = 0; c < content.length; c++) {
              newArray[c] = content[c];
          }

          // 3) Let the old array point to the new array
          content = newArray;
      }

      //Add the item to the content of the array list
      content[size] = item;
      size++;
   } 
}

这给出了错误

public class GenericQueue<E> {
   private int initialCapacity = 10;
   private int size = 0;
   private int[] content = new int[initialCapacity];

   public static <E> void add(E item) {
      int size = 0;
      int[] content;

      // If we run out of space in the array
      if (size == content.length) {

          // 1) Create a new, larger array (2x)
          int[] newArray = new int[content.length * 2];

          // 2) Copy the content from the old array to the new one
          for (int c = 0; c < content.length; c++) {
              newArray[c] = content[c];
          }

          // 3) Let the old array point to the new array
          content = newArray;
      }

      //Add the item to the content of the array list
      content[size] = item;
      size++;
   } 
}

由于某种原因,仅使用通用方法标头并不能使代码正常工作。我想念什么?”


答案:

您缺少一些东西。首先,您的add方法不应为静态,否则您将始终只有一个列表。

所以:

GenericQueue.java:26: error: incompatible types: E cannot be converted to int
      content[size] = item;
                      ^
  where E is a type-variable:
    E extends Object declared in method <E>add(E)
1 error

应为:

   public static <E> void add(E item) {

第二,您有两个名为 public void add(E item) { 的数组,一个是字段内容,另一个是content内部的局部变量。应该从代码中删除局部变量,以免掩盖该字段。同样,您有一个add的局部变量,应将其从添加方法中删除。

所以:

size

应成为:

   public static <E> void add(E item) {
      int size = 0;
      int[] content;

您缺少对代码的更改,这些更改期望您的数据为整数。 泛化代码时,您需要考虑泛化代码的哪一部分。在这种情况下,您要创建一个适用于任何一种数据类型的列表。您的初始列表使用整数数组来保存数据,因此整数数组将需要更改为任何类型的数组,即您的通用符号。对于您的情况E。这意味着具有整数数组的所有代码案例都应转换为具有E数组的代码。唯一的例外是数组的实例化,因为您不能使用泛型实例化数组,而需要使用Object。

使用int数组的部分是:

   public void add(E item) {
private int[] content = new int[initialCapacity];

这些可以如下更改:

int[] newArray = new int[content.length * 2];
private E[] content = new Object[initialCapacity];

您可能会问,制作E[] newArray = new Object[content.length * 2]; 的列表与泛型类型的列表有何区别?由于Object是所有类类型的父级,因此Object的列表可以保存不同类型的对象(例如Integers和Strings)的数据,而通用列表则必须选择一种类型的对象,并且所有对象都必须是该类型。有了这种保证,就可以更轻松地使用列表,因为您无需在使用前检查列表中项目的类型。