【问题标题】:Generic list print method通用列表打印方法
【发布时间】:2014-01-06 19:14:57
【问题描述】:

我正在尝试编写一个通用的打印方法,适用于所有实现“Iterable”接口的类

public class List<T> {

    public static <T extends Iterable<T>> void print(T[] list){
        for (Object element : list){
            System.out.println(element);
        }
    }
    public static void main(String[] args){
        ArrayList<Integer> l = new ArrayList();
        l.add(1);
        l.add(5);
        l.add(3);
        l.add(2);
        print(l);
    }
}

但我收到错误“List 类型中的方法 print(T[]) 不适用于参数 (ArrayList)”

【问题讨论】:

  • 您可能不想将您的班级命名为List。此外,class List&lt;T&gt; 中的Tpublic static &lt;T extends Iterable&lt;T&gt;&gt; void print(T[] list) 中的T 不同。

标签: java list generics


【解决方案1】:

您的参数是T[]。这是一个扩展Iterable 类型的数组。你只需要T。但是您还需要一个类型变量作为Iterable 中的类型参数。你需要

public static <T extends Iterable<E>, E> void print(T list) {

您需要这个,因为您不想要 Iterable&lt;ArrayList&gt;,这是您当前实现中的内容。

【讨论】:

  • 我认为print(Iterable&lt;?&gt;) 也可以,除非我读得太快。
  • @PaulBellora 是的,你是对的。这也有效(在这种情况下可能更好)。玩泛型很有趣。
【解决方案2】:

您的通用定义不正确。您正在尝试将边界设置为 &lt;T extends Iterable&lt;T&gt;&gt;,但通用参数 (Integer) 不是 T

您可以通过引入一个单独的通用参数来使其工作:一个表示集合,一个表示集合的值。

旁注:你根本不需要T[]。你只想要T

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> l = new ArrayList<>();
        l.add(1);
        l.add(5);
        l.add(3);
        l.add(2);
        print(l);
    }

    public static <S, T extends Iterable<S>> void print(T list){
        for (Object element : list){
            System.out.println(element);
        }
    }
}

输出

1
5
3
2

【讨论】:

    【解决方案3】:

    由于System.out.println 接受所有Objects,并且您并没有真正在方法中使用泛型,我认为根本没有理由使用泛型。这段代码将完成同样的事情:

    public static void print(Iterable<?> list) {
        for (Object element : list) {
            System.out.println(element);
        }
    }
    

    你做了什么

    我还想补充一点,您对T[] 有点困惑。 T[] 表示“一个 T 类型的 数组”。但是你试图传递一个 ArrayList,它与 array 不同(ArrayList 类在内部使用常规数组,但这无关紧要) .

    让我们看看你原来的方法声明:

    public static <T extends Iterable<T>> void print(T[] list) {
        for (Object element : list) {
            System.out.println(element);
        }
    }
    

    此方法被声明为接受一个参数:泛型类型 T 的数组,其中泛型类型 T 可迭代泛型类型 T。

    让我们再读一遍最后一部分:泛型类型 T 在泛型类型 T 上是可迭代的。

    也就是说,泛型类型应该可以对其自身进行迭代。

    你需要一个这样的类来使用你当前的print 方法:

    class MyClass implements Iterable<MyClass> {
        ...
    }
    

    然后像这样使用你的打印方法:

    MyClass[] objects = new MyClass[5];
    print(objects);
    

    但是,使用您当前的打印方法,它只会为数组中的 5 个元素中的每一个调用 MyClass.toString 方法。

    【讨论】:

      【解决方案4】:

      如果 T 扩展 Iterable 则只需这样做:

      public static <E, T extends Iterable<E>> void print(T list){
              for (Object element : list){
                  System.out.println(element);
              }
      }
      

      编辑:您声明的是T extends Iterable&lt;T&gt;,例如可以是Iterable,这可能不是您想要实现的。然后只需添加另一种类型的列表元素。

      如果您不专门使用该类型,那么您也可以将泛型类型声明为:

      <T extends Iterable<?>>
      

      【讨论】:

      • 它也不会编译。
      • 是的,我只是更仔细地查看他的通用定义,这可能是不正确的..
      猜你喜欢
      • 2013-03-24
      • 2019-05-08
      • 1970-01-01
      • 2021-09-11
      • 1970-01-01
      • 2017-10-18
      相关资源
      最近更新 更多