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


236

我正在尝试打印a的所有元素List,但是它打印的是指针Object而不是值。

这是我的打印代码...

for(int i=0;i<list.size();i++){
    System.out.println(list.get(i));
} 

任何人都可以帮助我,为什么它没有体现出要素的价值。


3
您声明的List是哪种类型?向我们展示您如何声明和实例化它。
Makoto 2012年

您必须调用toString,然后获得类的说明或重写列表包含的类型的toString方法
L7ColWinters 2012年

那就是您要打印的内容-您需要一个不同的toString或其他可读字符串。
戴夫·牛顿

ArrayList <class> list =新的ArrayList <class>();
user1335361'4

4
请注意,您可以使用更紧凑的语法来完成同一件事: for (Object obj : list) {System.out.println(obj);}
aroth

Answers:


114

这是有关打印出列表组件的一些示例:

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;
    }
}

1
Model课程介绍与问题有什么关系?
Karl Richter

4
这只是一个假设,因为我不知道列表中的对象是哪种。
Crazenezz

477

以下是紧凑的,并且避免了示例代码中的循环(并为您提供了漂亮的逗号):

System.out.println(Arrays.toString(list.toArray()));

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


18
大约只有什么list.toString()
Jaskey 2014年

22
仅使用'list.toString()'不会打印单个元素,除非它是List接口的自定义实现,该实现重写了正常行为(或多或少打印类名和哈希码)。
Holly Cummins 2014年

1
如果他们使用自定义类而不进行覆盖toString,则您的解决方案还将打印其类名和哈希码。
Jaskey 2014年

它打印为[value1,value2,value3]。是否可以不使用[]打印?
截至

实际上,@ Jaskey是正确的-他们的答案是一个更好的答案。该Arrays方法对数组很有用,但现在对的子类不再需要AbstractCollection
Holly Cummins

100

从Java 8开始,List继承了默认的“ forEach”方法,您可以将其与方法引用“ System.out :: println”结合使用,如下所示:

list.forEach(System.out::println);

2
@Katja Hahn,是否可以在println输出之前附加或添加一些字符串?
gumkins

2
@gumkins,是的,可以。示例:Arrays.stream(new String [] {“ John”,“ Sansa”,“ Cersei”})。map(s->“ Hi” + s +“!”)。forEach(System.out :: println) ;
蒂亚戈·穆西

40
System.out.println(list);//toString() is easy and good enough for debugging.

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;
    }
}

输出:

[string1, string2]
[student Tom age:15, student Kate age:16]

因为这个答案并不完全正确。它使用多态性而没有意识到。以下是的实际继承层次结构listList -> Collection -> Iterable -> Object。实际上从AbstractCollection继承的类是ArrayList。因此,在此示例中,当toString()调用时,它将找到ArrayList中定义的实现AbstractCollection。请注意以下继承层次ArrayListArrayList -> AbstractList -> AbstractCollection -> Collection -> Iterable -> Object
anon58192932 '18

20

Java 8 Streams方法...

list.stream().forEach(System.out::println);

答案与Katja Hahn的答案相同
Karl Richter

不,不是。矿山利用stream()。
布拉德利D

@BradleyD通过在其中添加另一层方法调用可以实现什么收益?
里昂,

15

列表中的对象必须已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();
    }
}

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

t1 = Test$T1@19821f
t2 = 5

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


11

考虑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)

这些方法彼此之间有何不同?

第一种方法(Iterable.forEach)- 通常使用collection的迭代器,并且将迭代器设计为快速失败的,这意味着ConcurrentModificationException如果在迭代过程中对基础collection进行了结构修改,则它将抛出该迭代器。如文档中所述ArrayList

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

因此,这意味着ArrayList.forEach可以毫无问题地设置该值。并且在并发收集的情况下,例如ConcurrentLinkedQueue,迭代器将是弱一致性的,这意味着forEach允许传入的动作进行均匀的结构更改,而ConcurrentModificationException不会引发异常。但是,此处的修改在该迭代中可能可见,也可能不可见。

第二种方法(Stream.forEach)- 顺序不确定。尽管对于顺序流可能不会发生,但是规范并不能保证。同样,该动作本质上必须是无干扰的。如文档中所述

此操作的行为明确地是不确定的。对于并行流管道,此操作不能保证尊重流的遇到顺序,因为这样做会牺牲并行性的好处。

第三种方法(Stream.forEachOrdered)- 将按照流的遇到顺序执行操作。因此,无论何时订购都可以使用,forEachOrdered无需再三思。如文档中所述:

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

在迭代同步集合时第一种方法将获取集合的锁一次,并将其保留在所有对action方法的调用中,但是在流的情况下,它们使用集合的分隔符,该分隔符不会锁定并且依赖于已建立的non -干扰。如果收集支持在迭代期间修改了流,ConcurrentModificationException则将抛出该结果或可能出现不一致的结果。

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

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




7

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

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

.....inserted value in list.......

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

for(int i=0;i<leaveDatesList.size();i++){
    System.out.println(leaveDatesList.get(i));
}

方法2:在forEach,for循环中打印列表

for(Integer leave : leaveDatesList){
    System.out.println(leave);
}

方法3:在Java 8中打印列表

leaveDatesList.forEach(System.out::println);

5
  1. 您尚未指定列表包含的元素类型(如果它是原始数据类型)则可以打印出元素。
  2. 但是,如果元素是对象,则正如Kshitij Mehta所述,您需要在该对象内实现(重写)方法“ toString”(如果尚未实现),并使其从对象内部返回完整的含义,例如:

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

3

System.out.println(list); 为我工作。

这是一个完整的示例:

import java.util.List;    
import java.util.ArrayList;

public class HelloWorld {
     public static void main(String[] args) {
        final List<String> list = new ArrayList<>();
        list.add("Hello");
        list.add("World");
        System.out.println(list);
     }
}

它将打印[Hello, World]


与其他更早的答案没有不同
Karl Richter

我给出了一个完整的示例,其中包含imports,class和main方法,您可以复制和粘贴并显示结果。因此,在我看来,没有理由将其否决
jfmg

3

有关字符串数组的列表

list.forEach(s -> System.out.println(Arrays.toString((String[]) s )));

2

我编写了一个转储函数,如果没有重写toString(),它基本上会打印出对象的公共成员。可以很容易地将其扩展为调用吸气剂。Javadoc:

使用以下规则将给定的对象转储到System.out:

  • 如果对象是可迭代的,则将其所有组件转储。
  • 如果对象或其超类之一覆盖toString(),则将“ toString”转储
  • 否则,将为该对象的所有公共成员递归调用该方法

/**
 * Dumps an given Object to System.out, using the following rules:<br>
 * <ul>
 * <li> If the Object is {@link Iterable}, all of its components are dumped.</li>
 * <li> If the Object or one of its superclasses overrides {@link #toString()}, the "toString" is dumped</li>
 * <li> Else the method is called recursively for all public members of the Object </li>
 * </ul>
 * @param input
 * @throws Exception
 */
public static void dump(Object input) throws Exception{
    dump(input, 0);
}

private static void dump(Object input, int depth) throws Exception{
    if(input==null){
        System.out.print("null\n"+indent(depth));
        return;
    }

    Class<? extends Object> clazz = input.getClass();
    System.out.print(clazz.getSimpleName()+" ");
    if(input instanceof Iterable<?>){
        for(Object o: ((Iterable<?>)input)){
            System.out.print("\n"+indent(depth+1));
            dump(o, depth+1);
        }
    }else if(clazz.getMethod("toString").getDeclaringClass().equals(Object.class)){
        Field[] fields = clazz.getFields();
        if(fields.length == 0){
            System.out.print(input+"\n"+indent(depth));
        }
        System.out.print("\n"+indent(depth+1));
        for(Field field: fields){
            Object o = field.get(input);
            String s = "|- "+field.getName()+": ";
            System.out.print(s);
            dump(o, depth+1);
        }
    }else{

        System.out.print(input+"\n"+indent(depth));
    }
}

private static String indent(int depth) {
    StringBuilder sb = new StringBuilder();
    for(int i=0; i<depth; i++)
        sb.append("  ");
    return sb.toString();
}

2

For循环打印列表内容:

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

for ( String elem : myList ) {
  System.out.println("Element : "+elem);
}

结果:

Element : AA
Element : BB

如果要单行打印(仅供参考):

String strList = String.join(", ", myList);
System.out.println("Elements : "+strList);

结果:

Elements : AA, BB

1
    list.stream().map(x -> x.getName()).forEach(System.out::println);

哪种类型x以及与OP的问题有什么关系?
Karl Richter

1

我碰巧现在正在为此工作...

List<Integer> a = Arrays.asList(1, 2, 3);
List<Integer> b = Arrays.asList(3, 4);
List<int[]> pairs = a.stream()
  .flatMap(x -> b.stream().map(y -> new int[]{x, y}))
  .collect(Collectors.toList());

Consumer<int[]> pretty = xs -> System.out.printf("\n(%d,%d)", xs[0], xs[1]);
pairs.forEach(pretty);

1

它取决于存储在中的对象的类型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();
 }  
}

测试:

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);
   }
}

0
public static void main(String[] args) {
        answer(10,60);

    }
    public static void answer(int m,int k){
        AtomicInteger n = new AtomicInteger(m);
        Stream<Integer> stream = Stream.generate(() -> n.incrementAndGet()).limit(k);
        System.out.println(Arrays.toString(stream.toArray()));
    }

0

尝试覆盖toString()方法,因为您希望该元素将为printend。因此打印方法可以是:

for(int i=0;i<list.size();i++){
    System.out.println(list.get(i).toString());
} 

这就是OP的代码所要做的。的调用toString是隐式的。
Karl Richter

-2
   List<String> textList=  messageList.stream()
                            .map(Message::getText)
                            .collect(Collectors.toList());

        textList.stream().forEach(System.out::println);
        public class Message  {

        String name;
        String text;

        public Message(String name, String text) {
            this.name = name;
            this.text = text;
        }

        public String getName() {
            return name;
        }

      public String getText() {
        return text;
     }
   }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.