打印任何类型的ArrayList元素的一般方法

时间:2014-02-24 18:34:00

标签: java arraylist

出于练习目的,我试图通过调用ArrayList方法来编写显示.toString()元素的通用方法。我们假设.toString()做我想做的事。

我想出了下面的解决方案,我的输入ArrayList的类型为Object

public void printArralyList(ArrayList<Object> list){
    for(Object o:list){
        System.out.print(o.toString());
    }
    System.out.println();
}

然而它不起作用!

printArralyList(new ArrayList<Integer>(Arrays.asList(1,2,3,5,8,13,21)));

我得到的编译错误是

    The method printArralyList(ArrayList<Object>) is not applicable
 for the arguments (ArrayList<Integer>

我该如何解决这个问题?

4 个答案:

答案 0 :(得分:2)

ArrayList<Integer>不是ArrayList<Object>,即使IntegerObject

您需要在方法的参数中使用通配符,因为您不关心泛型类型参数的类型。

public void printArralyList(ArrayList<?> list){

顺便提一下,您可以让自己的方法采用List代替ArrayList,并且不需要在Arrays.asList中包含ArrayList的返回值:

public void printArralyList(List<?> list){

printArralyList(Arrays.asList(1,2,3,5,8,13,21));

会起作用。

答案 1 :(得分:0)

你不需要泛型或通配符。您只需要一个简单的方法,它不会为参数指定任何类型,以便您可以随时传入ArrayList。

public void printArralyList(ArrayList list){
    for (Object o:list){
        System.out.print(o.toString());
    }
    System.out.println();
}

答案 2 :(得分:0)

rgettman在https://stackoverflow.com/a/21996188/

中解释了错误的原因

但是,如果是出于练习目的,你应该考虑练习多态和programming to an interface

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

这可以与ArrayList<Integer>参数一起使用,也可以与LinkedHashSet<JComponent>或其他任何实现Iterable接口的内容一起使用....

答案 3 :(得分:0)

回答你的问题。

声明ArrayList不等于ArrayList。即使Integer在类型层次结构中从Object传递。

要记住的重要一点是,当您声明Collection<String> myStrings时,您告诉编译器,只能为变量myString分配在String类型上创建的类的实例,并且集合。

 Collection<Object> myObjects; 

 myObjects = new ArrayList<String>(); //Exception
 myObjects = new HashSet<String>(); //Exception
 myObjects = new HashSet<Object>(); //Valid
 myObjects = new ArrayList<Object>(); //Valid
 myObjects = new ArrayList<Integer>(); //Exception

为了解决这样的问题,java提供了允许你传递它的Wildcars集。

有三种类型的支持卡支持各种variances

 <? extends T> - Covariance
 <? super T>   - Contravariance
 <?>           - Invariance/

关于他们的规则称为PECS

由于我们要使用列表元素,要删除编译错误,您应该使用协方差。

Collection<? extends Object> myObjects; 

 myObjects = new ArrayList<String>(); //Valid
 myObjects = new HashSet<String>(); //Valid
 myObjects = new HashSet<Object>(); //Valid
 myObjects = new ArrayList<Object>(); //Valid
 myObjects = new ArrayList<Integer>(); //Valid

在Java中,每个类都是从对象传递的,因此<? extends>在功能上等于<?>,这就是rgettman提出的答案

generics支持Java中的集合框架。您应该熟悉它们以从框架中充分受益。

另一种解决方法是从这样的通用方法中受益:

public static <T> void printList<Iterable<T> iterable) {

    for(T element : iterable){
        System.out.printf("%s ",element);
    }
    System.out.println();
} 

为何静电?

对static方法的调用更快,并且此方法与任何类成员无关。

是什么?

这是generic method的声明。它允许您定义泛型参数的值。 Java非常敏锐,它可以在版本7中大多数情况下自行提取它。

如果用Iterable<String>调用方法,那么如果Iterable为“整数”,则T的值为String

为什么可以使用?

Iterable是一个简单的界面,可让您使用for-each look。这意味着您将能够遍历类定义实现它的所有对象。

为什么选择printf?

printf函数使用Formatter,它的好处是两个   - 如果element的实例被赋值为null,则在调用它o.toString()时将不会出现空指针异常。

缺少什么?

在那个实现中仍然缺少两件事   - 输入验证   - 正确的输出格式,将元素与昏迷分开。