简体   繁体   English

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

[英]A general method to printout elements of an ArrayList of any type

For practicing purposes I am trying to write a general method to display the elements of an ArrayList by calling its .toString() method. 出于实践目的,我试图编写一个通用方法来通过调用它的.toString()方法来显示ArrayList的元素。 Let's please assume .toString() does what I want it to do. 让我们假设.toString()做我想做的事。

I came up with this solution below where my input ArrayList is of type Object : 我想出了下面的解决方案,我的输入ArrayListObject类型:

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

However it would not work! 但它不会起作用!

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

The compilation error I get is 我得到的编译错误是

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

how can I address that? 我怎么解决这个问题?

An ArrayList<Integer> is not an ArrayList<Object> , even though an Integer is an Object . ArrayList<Integer>不是ArrayList<Object> ,即使IntegerObject

You need a wildcard in your method's parameter, because you don't care what type the generic type parameter is. 您需要在方法的参数中使用通配符,因为您不关心泛型类型参数的类型。

public void printArralyList(ArrayList<?> list){

Incidentally, you can have your method take a List instead of an ArrayList , and there would be no need to wrap the return of Arrays.asList in an ArrayList : 顺便说一句,您可以让您的方法采用List而不是ArrayList ,并且不需要在ArrayList包装Arrays.asList的返回:

public void printArralyList(List<?> list){

and

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

would work. 会工作。

You dont need Generics or wildcard. 你不需要泛型或通配符。 All you need is a simple method which does not specify any type for the argument so that you can pass in an ArrayList of anytime. 您只需要一个简单的方法,它不会为参数指定任何类型,以便您可以随时传入ArrayList。

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

The reason for the error was explained by rgettman in https://stackoverflow.com/a/21996188/ 出现错误的原因由rgettman在https://stackoverflow.com/a/21996188/中解释

However, if it is for practicing purposes, you should consider practicing polymorphism and programming to an interface 但是,如果是出于练习目的,您应该考虑对接口进行多态和编程

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

This can be used with an ArrayList<Integer> parameter, as well as with an LinkedHashSet<JComponent> , or anything else that implements the Iterable interface.... 这可以与ArrayList<Integer>参数一起使用,也可以与LinkedHashSet<JComponent> ,或者实现Iterable接口的任何其他内容....

Answering your question. 回答你的问题。

The declaration ArrayList does not equal to ArrayList. 声明ArrayList不等于ArrayList。 Even if an Integer is delivered from Object in type hierarchy. 即使从类型层次结构中的Object传递Integer也是如此。

Important thing to remember is that when you declare Collection<String> myStrings , you tell to compiler, that to variable myString can be assigned only instances of class that are created upon String type and are Collections. 需要记住的重要一点是,当您声明Collection<String> myStrings ,您告诉编译器,对于变量myString只能分配在String类型上创建的类的实例,并且是Collections。

 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

To solve problems like that, java provide set of Wildcars that allow you to pass this. 为了解决这样的问题,java提供了一组允许你传递它的Wildcars

There are three type of will card that support various variances . 有三种类型的意志卡支持各种差异

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

The rule about them is called PECS 有关它们的规则称为PECS

As we want to consume the list elements, to remove the compilations errors you should use Covariance. 由于我们要使用列表元素,要删除编译错误,您应该使用协方差。

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

As in Java every class is delivered from object so <? extends> 在Java中,每个类都是从对象传递的,所以<? extends> <? extends> is functionally equal to <?> , and that is what rgettman has proposed as answer <? extends>在功能上等于<?> ,这就是rgettman提出的答案

The collection framework in Java is supported with generics . Java中的集合框架由泛型支持。 You should get familiar with them to fully benefit from the framework. 您应该熟悉它们以从框架中充分受益。

A different way to solve is is to benefit from generic methods like this: 另一种解决方法是从这样的通用方法中受益:

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

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

Why static ? 静电为什么?

The call to static method are faster and this method is not related to any class member. 对static方法的调用更快,并且此方法与任何类成员无关。

What is ? 什么是 ?

This is declaration of an generic method . 这是通用方法的声明。 It allow you to define the value for generic parameter. 它允许您定义泛型参数的值。 And Java is so keen that it can extract it by itself is most cases in version 7. Java非常热衷于它可以自己提取它在版本7中的大多数情况。

If you call the method with Iterable<String> then the value of T will be String if Iterable then `Integer'. 如果用Iterable<String>调用该方法,那么T的值将是String如果是Iterable,那么是'Integer'。

Why Iterable ? 为什么可以进行?

The Iterable is a simple interface that allows you to use for-each look . Iterable是一个简单的界面,允许您使用for-each外观 This mean you will be able to iterate through all object that classes definition implements it. 这意味着您将能够遍历类定义实现它的所有对象。

Why printf ? 为什么printf?

The printf function use Formatter , the benefits from it are two - In case when instance of element is assigned with null, you will not get null pointer exception that will occur if you call it o.toString() . printf函数使用Formatter ,它的好处是两个 - 如果element实例被赋值为null,那么如果你将它o.toString() ,你将不会得到空指针异常。

What is missing ? 什么东西少了 ?

In that implementation is still missing two things - The input validation - The proper output format that will separate the elements with a coma. 在那个实现中仍然缺少两件事 - 输入验证 - 将元素与昏迷分开的正确输出格式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM