【问题标题】:Java: <E extends Comparable <E>>Java:<E 扩展了可比较的 <E>>
【发布时间】:2017-04-27 03:29:47
【问题描述】:

所以这个程序尝试使用如下命令行参数:

S 4 1 2 3 4 4

args[0]是数组类型

args[1]是数组长度

args[2...] 是数组中的值

args[length-1] 是一个将用于线性搜索的键

public class whatTheFoo{

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static <E> void main(String[] args) {

        for(int i=0;i<args.length;i++)System.out.print(args[i]);
        System.out.println();

        int arraySize = Integer.parseInt(args[1]);
        E[] array = (E[])new Object[arraySize];
        E key = null;

        if (args[0].matches("I|i")) {
            for (int i = 2; i < args.length-1; i++) {
                array[i-2]=(E)new Integer(args[i]);
                System.out.println(array[i-2]);
            }
            key = (E) new Integer(args[args.length-1]);
            System.out.println("Key is: " + key);
        } 

    ...

        if(linearSearch(array, key)<0)
            System.out.println("Didnt find it");
        else 
            System.out.println("Found it at index: "+(linearSearch(array, key)-1));
    }

    public static <E> int linearSearch(E[]array,E key) {
        int index=-1;
        for(int i=0;i<array.length;i++) {
            if(array[i].equals(key)){
                index = (int) array[i];
            }
        }
        return index;
    }
}

这可行,但是当我将 linearSearch 方法更改为:

public static <E extends Comparable<E>> int linearSearch(E[]array,E key) 

我收到错误消息:

The method linearSearch(E[], E extends Comparable<E>) in the type Prog7b is not applicable for the arguments (E[], E)

但如果我将 main 更改为:

public static <E extends Comparable<E>> void main(String[] args) {

我明白了:

 Exception in thread "main" I412344java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;
at whatTheFoo.main(whatTheFoo.java:10)

该方法已被指示包含在该方法中:

<E extends Comparable<E>>. 

我哪里错了?谢谢阅读。

-------------------------------------------------------------------

对于那些可能好奇的人,这是提供的所有帮助的最终结果。再次感谢!

public class Prog7b {

//  @SuppressWarnings({ "unchecked", "rawtypes" })
    public static void main(String[] args) {

        if (args[0].matches("I|i")) {
            Integer[] array = new Integer[Integer.parseInt(args[1])];
            for (int i = 2; i < args.length - 1; i++) {
                array[i - 2] = new Integer(args[i]);
            }
            Integer key = new Integer(args[args.length - 1]);
            if (linearSearch(array, key) < 0) {
                System.out.println("Didnt find it");
            } else
                System.out.println("Found it at index: " + (linearSearch(array, key) - 1));
            System.out.println("The max of the array is: " + max(array));
            print(array);
        } else if (args[0].matches("S|s")) {
            String[] array = new String[Integer.parseInt(args[1])];
            for (int i = 2; i < args.length - 1; i++) {
                array[i - 2] = new String(args[i]);
            }
            String key = new String(args[args.length - 1]);
            if (linearSearch(array, key) < 0) {
                System.out.println("Didnt find it");
            } else
                System.out.println("Found it at index: " + (linearSearch(array, key) - 1));
            System.out.println("The max of the array is: " + max(array));
            print(array);
        } else {
            Double[] array = new Double[Integer.parseInt(args[1])];
            for (int i = 2; i < args.length - 1; i++) {
                array[i - 2] = new Double(args[i]);
            }
            Double key = new Double(args[args.length - 1]);
            if (linearSearch(array, key) < 0) {
                System.out.println("Didnt find it");
            } else
                System.out.println("Found it at index: " + (linearSearch(array, key) - 1));
            System.out.println("The max of the array is: " + max(array));
            print(array);
        }
    }

    public static <E extends Comparable<E>> int linearSearch(E[] array, E key) {
        int index = 0;
        for (int i = 0; i < array.length; i++) {
            index++;
            if (array[i].equals(key)) {
                return index;
            }
        }
        return -1;
    }

    public static <E extends Comparable<E>> E max(E[] list) {
        E max = list[0];
        for (int i = 1; i < list.length; i++) {
            if (max.compareTo(list[i]) < 0) {
                max = list[i];
            }
        }
        return max;
    }

    private static <E> void print(E[] list) {
        System.out.print("[");
        for (int i = 0; i < list.length - 1; i++)
            System.out.print(list[i] + ", ");
        System.out.print(list[list.length - 1] + "]\n");
    }
}

【问题讨论】:

  • 由于类型擦除,E 在运行时被Object 替换。我不确定你期望E 是什么类型。
  • 你为什么还需要E
  • 我假设我需要 E,因为数组的类型是在命令行参数中决定的,并且不是硬编码的。对于线性搜索,它应该接受任何数组,无论是 int、string 还是 double 并检查键值。
  • 您可以将E 保留在搜索方法中,但在您的主方法中不需要它,因为任何对象都可以传递给搜索方法。
  • 并提示:禁止这些警告是非常糟糕的做法。并且永远不要将更多信息放入 cmets!

标签: java arrays generics


【解决方案1】:

我不认为main 应该是通用的。 (方法声明中的&lt;E&gt; 部分声明了一个类型变量,这使其成为泛型。)如果main 真的应该是泛型的,那么你需要和你的老师谈谈,因为他们正在做一些奇怪的事情,我们可以'真的猜不到。

泛型是仅编译时的概念。基本上这个想法是你有一些代码实际上对特定类型有些不可知,但仍然需要一些关于它的抽象信息。

例如,假设我们有一些方法可以检查一个对象是否为空:

Object requireNonNull(Object obj) {
    if (obj == null) {
        throw new NullPointerException();
    } else {
        return obj;
    }
}

这很好。我们可以将任何类型的对象传递给该方法。 (IntegerString 等等。)但是如果我们想直接分配返回值呢?

我们希望能够做到这一点:

String mightBeNull = ...;
String definatelyNotNull = requireNonNull(mightBeNull);

这使我们的验证代码更整洁。 (也许不是检查 null,我们的验证实际上大约 10 行长,我们不想一直重复。)

好吧,就目前而言,我们不能,因为尝试将 Object 分配给 String 时会出现编译时错误。

不过,泛型让我们这样做:

<T> T requireNonNull(T obj) {
    if (obj == null) {
        throw new NullPointerException();
    } else {
        return obj;
    }
}

类型参数&lt;T&gt; 表示我们声明了一种临时类型。我们不关心它实际上是什么,但我们可以说该方法返回我们传递给它的任何内容。无论obj 是什么类型,在我们调用requireNonNull 时,该方法都会将该类型返回给调用者。

所以现在我们可以这样做了:

String  s = requireNonNull("");
Integer i = requireNonNull(10);
Float   f = requireNonNull(2f);

等等。

requireNonNull 实际上是一个真正的方法,它就是这样工作的。

不过,重点是泛型可以让您编写非常通用的 API,该 API 会被非泛型代码调用。

对于您的分配,您似乎应该编写一个泛型方法linearSearch,并带有一个有界类型参数&lt;E extends Comparable&lt;E&gt;&gt;(本质上意味着您传递给linearSearch 的任何数组类型,它必须是某个子类型Comparable)。那么你可能应该在main 中传递不同类型的数组,比如Integer[]String[] 等。你的main 方法不会是通用的。对于args[0] 所需的每种类型,您将只拥有一个if...else if 链。

【讨论】:

  • 我更改了条件,因此他们创建了常规数组,但是当我尝试将数组传递给方法时出现错误:Prog7b 类型中的方法 linearSearch(E[], E) 不适用对于参数 (int[], int)
  • 如果您想将它们传递给通用代​​码,您必须使用盒装类(Integer[]Boolean[]Character[] 等)。你可以例如从intInteger 的自动装箱,但不适用于像int[]Integer[] 这样的数组。
  • 为将来可能想知道类似问题的任何人添加了完整的修订代码。好的做法还是通常不做的事情?
  • 没关系。如果将问题更改为让未来的读者感到困惑或使答案不再相关,那只会是不好的。 (例如,有时人们实际上会删除完全不起作用的代码并将其替换为起作用的代码,这样您就无法理解问题最初是关于什么的。这样的事情很糟糕。)您可以发布完成的如果您愿意,可以将代码作为答案,但我不会太担心。
  • 知道了。所以我对原帖所做的应该没问题。未来的读者可以看到旧代码以及它是如何修改的。感谢您的洞察力!它确实有帮助。
猜你喜欢
  • 1970-01-01
  • 2014-12-08
  • 1970-01-01
  • 2010-12-26
  • 2015-06-17
  • 2011-01-11
  • 2010-11-24
相关资源
最近更新 更多