如何在Java中打印出List的所有元素?

use*_*361 219 java list

我试图打印出a的所有元素List,但它是打印指针Object而不是值.

这是我的打印代码......

for(int i=0;i<list.size();i++){
    System.out.println(list.get(i));
} 
Run Code Online (Sandbox Code Playgroud)

谁能帮助我,为什么它不打印元素的价值.

Hol*_*ins 437

以下是紧凑的,并避免示例代码中的循环(并给你很好的逗号):

System.out.println(Arrays.toString(list.toArray()));
Run Code Online (Sandbox Code Playgroud)

但是,正如其他人所指出的那样,如果您没有为列表中的对象实现合理的toString()方法,您将获得您正在观察的对象指针(实际上是哈希码).无论他们是否在列表中,都是如此.

  • 只使用'list.toString()'不会打印单个元素,除非它是List接口的自定义实现,它覆盖了正常行为(打印类名和哈希码,或多或少). (21认同)
  • 那么只有`list.toString()`. (16认同)
  • 那么System.out.println(列表)呢?有用. (7认同)

Cra*_*ezz 104

这是一个关于打印列表组件的示例:

public class ListExample {

    public static void main(String[] args) {
        List<Model> models = new ArrayList<>();

        // TODO: First create your model and add to models ArrayList, to prevent NullPointerException for trying this example

        // Print the name from the list....
        for(Model model : models) {
            System.out.println(model.getName());
        }

        // Or like this...
        for(int i = 0; i < models.size(); i++) {
            System.out.println(models.get(i).getName());
        }
    }
}

class Model {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这只是一个假设,因为我不知道列表中的对象是什么类型. (4认同)
  • `Model` 类的引入与问题有什么关系? (2认同)

小智 92

从Java 8开始,List继承了一个默认的"forEach"方法,你可以将它与方法引用"System.out :: println"结合起来,如下所示:

list.forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

  • @Katja Hahn,是否可以在`println`输出中附加或前置一些字符串? (2认同)
  • @gumkins,是的,你可以.示例:Arrays.stream(new String [] {"John","Sansa","Cersei"}).map(s - >"Hi"+ s +"!").forEach(System.out :: println) ; (2认同)

Jas*_*key 37

System.out.println(list);//toString() is easy and good enough for debugging.
Run Code Online (Sandbox Code Playgroud)

toString()AbstractCollection 将是干净,很容易的做到这一点.AbstractList是一个子类AbstractCollection,所以不需要for循环,也不需要toArray().

返回此集合的字符串表示形式.字符串表示由一个集合元素的列表组成,它们的迭代器返回它们的顺序,用方括号("[]")括起来.相邻元素由字符","(逗号和空格)分隔.通过String.valueOf(Object)将元素转换为字符串.

如果您在列表中使用任何自定义对象,比如Student,则需要覆盖其toString()方法(覆盖此方法总是好的)以获得有意义的输出

见下面的例子:

public class TestPrintElements {

    public static void main(String[] args) {

        //Element is String, Integer,or other primitive type
        List<String> sList = new ArrayList<String>();
        sList.add("string1");
        sList.add("string2");
        System.out.println(sList);

        //Element is custom type
        Student st1=new Student(15,"Tom");
        Student st2=new Student(16,"Kate");
        List<Student> stList=new ArrayList<Student>();
        stList.add(st1);
        stList.add(st2);
        System.out.println(stList);
   }
}


public  class Student{
    private int age;
    private String name;

    public Student(int age, String name){
        this.age=age;
        this.name=name;
    }

    @Override
    public String toString(){
        return "student "+name+", age:" +age;
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

[string1, string2]
[student Tom age:15, student Kate age:16]
Run Code Online (Sandbox Code Playgroud)

  • 为什么这不是公认的答案? (2认同)
  • 因为这个答案并不完全正确。它在没有意识到的情况下使用了多态性。下面是`list`的实际继承层次结构:`List -&gt; Collection -&gt; Iterable -&gt; Object`。实际上从 AbstractCollection 继承的类是 `ArrayList`。所以在这个例子中,当调用 `toString()` 时,它会找到在 `AbstractCollection` 中定义的 `ArrayList` 实现。注意`ArrayList`的继承层次结构:`ArrayList -&gt; AbstractList -&gt; AbstractCollection -&gt; Collection -&gt; Iterable -&gt; Object` (2认同)

Luk*_*ski 27

Use String.join() for example:

System.out.print(String.join("\n", list));
Run Code Online (Sandbox Code Playgroud)


Bra*_*y D 20

Java 8 Streams方法......

list.stream().forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

  • @BradleyD 通过在那里添加另一层方法调用实现了什么收益? (6认同)

K M*_*hta 14

列表中的对象必须已toString实现,以便为屏幕打印有意义的内容.

这是一个快速测试,看看差异:

public class Test {

    public class T1 {
        public Integer x;
    }

    public class T2 {
        public Integer x;

        @Override
        public String toString() {
            return x.toString();
        }
    }

    public void run() {
        T1 t1 = new T1();
        t1.x = 5;
        System.out.println(t1);

        T2 t2 = new T2();
        t2.x = 5;
        System.out.println(t2);

    }

    public static void main(String[] args) {        
        new Test().run();
    }
}
Run Code Online (Sandbox Code Playgroud)

当执行此操作时,打印到屏幕的结果为:

t1 = Test$T1@19821f
t2 = 5
Run Code Online (Sandbox Code Playgroud)

由于T1不会覆盖toString方法,因此它的实例t1打印出来的东西不是很有用.另一方面,T2覆盖toString,因此我们控制它在I/O中使用时打印的内容,我们在屏幕上看到一些更好的东西.


i_a*_*ero 9

考虑List<String> stringList使用Java 8构造可以以多种方式打印的内容:

stringList.forEach(System.out::println);                            // 1) Iterable.forEach
stringList.stream().forEach(System.out::println);                   // 2) Stream.forEach (order maintained generally but doc does not guarantee)
stringList.stream().forEachOrdered(System.out::println);            // 3) Stream.forEachOrdered (order maintained always)
stringList.parallelStream().forEach(System.out::println);           // 4) Parallel version of Stream.forEach (order not maintained)
stringList.parallelStream().forEachOrdered(System.out::println);    // 5) Parallel version ofStream.forEachOrdered (order maintained always)
Run Code Online (Sandbox Code Playgroud)

这些方法如何彼此不同?

First Approach(Iterable.forEach) - 通常使用集合的迭代器,它被设计为快速失败,这意味着ConcurrentModificationException如果在迭代期间对底层集合进行结构修改,它将抛出.如文档中所述ArrayList:

结构修改是添加或删除一个或多个元素或显式调整后备数组大小的任何操作; 仅设置元素的值不是结构修改.

所以它意味着ArrayList.forEach设置值是允许没有任何问题.在并发收集的情况下,例如ConcurrentLinkedQueue迭代器将是弱一致的,这意味着forEach允许传入的动作甚至在没有ConcurrentModificationException异常的情况下进行结构更改.但是在这里,修改可能会或可能不会在该迭代中可见.

第二种方法(Stream.forEach) - 订单未定义.虽然顺序流可能不会发生,但规范并不能保证.此外,该行动也必须是非干扰性的.如文档中所述:

此操作的行为明确是不确定的.对于并行流管道,此操作不保证遵守流的遭遇顺序,因为这样做会牺牲并行性的好处.

第三种方法(Stream.forEachOrdered) - 动作将按流的遭遇顺序执行.因此,无论何时订单都在不加思索地使用forEachOrdered.如文档中所述:

如果流具有已定义的遭遇顺序,则按流的遭遇顺序对此流的每个元素执行操作.

在迭代同步集合时,第一种方法会将集合的锁定一次并将其保存在所有调用操作方法中,但是在流的情况下,它们使用集合的分裂器,它不会锁定并依赖于已经建立的非规则-干扰.如果在迭代期间修改了流的集合,ConcurrentModificationException则会抛出或者可能发生不一致的结果.

第四种方法(并行Stream.forEach) - 如前所述,无法保证在并行流的情况下遵守预期的遭遇顺序.对于不同的元素,可能在不同的线程中执行操作,这是不可能的forEachOrdered.

第五种方法(并行Stream.forEachOrdered) -forEachOrdered将处理在通过不考虑这一事实的源指定的顺序的要素流是否是顺序的或并联的.因此,将它与并行流一起使用是没有意义的.


小智 9

我也遇到过类似的问题。我的代码:

List<Integer> leaveDatesList = new ArrayList<>();

.....inserted value in list.......
Run Code Online (Sandbox Code Playgroud)

方式1:在for循环中打印列表

for(int i=0;i<leaveDatesList.size();i++){
    System.out.println(leaveDatesList.get(i));
}
Run Code Online (Sandbox Code Playgroud)

方式 2:在 forEach、for 循环中打印列表

for(Integer leave : leaveDatesList){
    System.out.println(leave);
}
Run Code Online (Sandbox Code Playgroud)

方式3:在java 8中打印列表

leaveDatesList.forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)


Ajm*_*sha 8

通过使用java 8功能.

import java.util.Arrays;
import java.util.List;

/**
 * @author AJMAL SHA
 *
 */
public class ForEach {

    public static void main(String[] args) {

        List<String> features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");
        (features).forEach(System.out::println);

    }

}
Run Code Online (Sandbox Code Playgroud)

  • `features.forEach(System.out :: println);`这就是我们这样做的方式.`()` - 这些是多余的,没有意义! (2认同)

小智 8

或者您可以简单地使用Apache Commons实用程序:

https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/ArrayUtils.html#toString-java.lang.Object-

List<MyObject> myObjects = ...
System.out.println(ArrayUtils.toString(myObjects));
Run Code Online (Sandbox Code Playgroud)


Shr*_*thy 7

这取决于 中存储的对象类型List,以及它是否具有toString()方法的实现。System.out.println(list)应该打印所有标准 java 对象类型(StringLongInteger)。如果我们使用自定义对象类型,那么我们需要override toString()自定义对象的方法。

例子:

class Employee {
 private String name;
 private long id;

 @Override
 public String toString() {
   return "name: " + this.name() + 
           ", id: " + this.id();
 }  
}
Run Code Online (Sandbox Code Playgroud)

测试:

class TestPrintList {
   public static void main(String[] args) {
     Employee employee1 =new Employee("test1", 123);
     Employee employee2 =new Employee("test2", 453);
     List<Employee> employees = new ArrayList(2);
     employee.add(employee1);
     employee.add(employee2);
     System.out.println(employees);
   }
}
Run Code Online (Sandbox Code Playgroud)


Sam*_*Sam 5

  1. 您没有指定列表包含哪种元素,如果它是原始数据类型,则可以打印出元素.
  2. 但是如果元素是对象,那么就像Kshitij Mehta所提到的那样,你需要在该对象中实现(覆盖)方法"toString" - 如果它尚未实现 - 并让它从对象中返回一些意义为完整的东西,例如:

    class Person {
        private String firstName;
        private String lastName;
    
        @Override
        public String toString() {
            return this.firstName + " " + this.lastName;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)


小智 5

对于 String 数组的列表

list.forEach(s -> System.out.println(Arrays.toString((String[]) s )));
Run Code Online (Sandbox Code Playgroud)


Thé*_*lia 5

For 循环打印列表的内容:

List<String> myList = new ArrayList<String>();
myList.add("AA");
myList.add("BB");

for ( String elem : myList ) {
  System.out.println("Element : "+elem);
}
Run Code Online (Sandbox Code Playgroud)

结果 :

Element : AA
Element : BB
Run Code Online (Sandbox Code Playgroud)

如果您想打印一行(仅供参考):

String strList = String.join(", ", myList);
System.out.println("Elements : "+strList);
Run Code Online (Sandbox Code Playgroud)

结果 :

Elements : AA, BB
Run Code Online (Sandbox Code Playgroud)