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

Posted

技术标签:

【中文标题】如何在 Java 中打印出 List 的所有元素?【英文标题】:How to print out all the elements of a List in Java? 【发布时间】:2012-04-27 10:12:24 【问题描述】:

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

这是我的打印代码...

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

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

【问题讨论】:

您将List 声明为什么类型?向我们展示您是如何声明和实例化它的。 你必须调用 toString 并且你会得到类的解释或者重写列表包含的类型的 toString 方法 这就是你告诉它要打印的——你需要一个不同的 toString 或其他可读的字符串。 ArrayList list= new ArrayList(); 请注意,您可以使用更紧凑的语法来完成同样的事情:for (Object obj : list) System.out.println(obj); 【参考方案1】:

以下内容简洁,避免了示例代码中的循环(并为您提供了漂亮的逗号):

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

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

【讨论】:

只有list.toString() 仅使用 'list.toString()' 不会打印单个元素,除非它是 List 接口的自定义实现,它覆盖了正常行为(打印类名和哈希码,或多或少)。 如果他们使用自定义类并且不覆盖toString,您的解决方案还将打印其类名和哈希码。 打印为 [value1,value2,value3]。我们可以在没有 [] 的情况下打印吗? 实际上,@Jaskey 是对的——他们的答案更好。 Arrays 方法对数组很有帮助,但现在不需要 AbstractCollection 的子类。【参考方案2】:

以下是一些关于打印出列表组件的示例:

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;
    

【讨论】:

Model类的介绍与问题有什么关系? 这只是一个假设,因为我不知道列表中的对象是什么样的。【参考方案3】:

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

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

【讨论】:

@Katja Hahn,是否可以在println 输出中附加或添加一些字符串? @gumkins,是的,你可以。示例:Arrays.stream(new String[] "John", "Sansa", "Cersei" ).map(s -> "Hi " + s + "!").forEach(System.out::println) ; 哇,谢谢! 对于 java/android:调用需要 API 级别 24(当前最低为 21):java.lang.Iterable#forEach【参考方案4】:
System.out.println(list);//toString() is easy and good enough for debugging.

AbstractCollection 中的toString() 将干净且容易做到这一点AbstractListAbstractCollection 的子类,所以不需要 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]

【讨论】:

因为这个答案并不完全正确。它在没有意识到的情况下使用多态性。这是list 的实际继承层次结构:List -&gt; Collection -&gt; Iterable -&gt; Object。实际上从 AbstractCollection 继承的类是ArrayList。所以在这个例子中,当toString()被调用时,它会找到ArrayListAbstractCollection中定义的实现。注意ArrayList 的继承层次结构:ArrayList -&gt; AbstractList -&gt; AbstractCollection -&gt; Collection -&gt; Iterable -&gt; Object【参考方案5】:

使用String.join() 例如:

System.out.print(String.join("\n", list));

【讨论】:

【参考方案6】:

Java 8 Streams 方法...

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

【讨论】:

与 Katja Hahn 的答案相同 不,不是。我的利用 stream()。 @BradleyD 在那里添加另一层方法调用实现了什么收益?【参考方案7】:

列表中的对象必须实现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 中使用时打印的内容,并且我们在屏幕上看到的效果更好。

【讨论】:

【参考方案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));

【讨论】:

【参考方案9】:

考虑一个List&lt;String&gt; 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)- 通常使用集合的迭代器,它被设计为fail-fast,这意味着如果底层集合在迭代期间被结构修改,它将抛出ConcurrentModificationException。正如doc 中提到的ArrayList

结构修改是添加或删除一个或 更多元素,或显式调整后备数组的大小;只是设置 元素的值不是结构修改。

所以这意味着对于ArrayList.forEach,设置该值是允许的,没有任何问题。在并发收集的情况下,例如ConcurrentLinkedQueue 迭代器将是 weakly-consistent,这意味着在 forEach 中传递的操作甚至可以进行结构更改,而不会引发 ConcurrentModificationExceptionexception。但这里的修改可能在该迭代中可见也可能不可见。

第二种方法 (Stream.forEach)- 订单未定义。虽然它可能不会发生在顺序流中,但规范并不能保证它。还要求该动作本质上是不干扰的。正如doc中提到的:

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

第三种方法 (Stream.forEachOrdered)- 该动作将按照流的遭遇顺序执行。因此,每当订单问题时,请毫不犹豫地使用forEachOrdered。正如doc中提到的:

遭遇中为该流的每个元素执行一个动作 流的顺序(如果流具有已定义的遇到顺序)。

在迭代同步集合时,第一种方法将获取集合的锁一次,并将在所有调用操作方法中保持它,但在流的情况下,它们使用collection的spliterator,它不锁定并且依赖于已经建立的不干涉规则。如果在迭代期间修改了支持流的集合,则会抛出 ConcurrentModificationException 或可能出现不一致的结果。

第四种方法(并行Stream.forEach)- 正如已经提到的,在并行流的情况下,不能保证按预期尊重相遇顺序。有可能在不同的线程中针对不同的元素执行操作,而 forEachOrdered 绝不会出现这种情况。

第五种方法(并行Stream.forEachOrdered)- forEachOrdered 将按照源指定的顺序处理元素,而不管流是顺序的还是并行的。所以将它与并行流一起使用是没有意义的。

【讨论】:

【参考方案10】:

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

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

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

方式一:在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);

【讨论】:

【参考方案11】:
    你还没有指定列表包含什么样的元素,如果是primitive data type那么你可以打印出元素。

    但是如果元素是对象,那么正如 Kshitij Mehta 所提到的,您需要在该对象中实现(覆盖)方法“toString” - 如果尚未实现 - 并让它从对象中返回一些有意义的东西,例如:

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

【讨论】:

【参考方案12】:

对于字符串数组的列表

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

【讨论】:

【参考方案13】:

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

【讨论】:

【参考方案14】:

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]

【讨论】:

与其他较早的答案没有什么不同 我给出了一个完整的示例,其中包含导入、类和主要方法,您可以复制和粘贴它们并显示结果。因此,我认为没有理由投票否决【参考方案15】:

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

例子:

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

【讨论】:

【参考方案16】:
    list.stream().map(x -> x.getName()).forEach(System.out::println);

【讨论】:

x 是什么类型,它与 OP 的问题有什么关系?【参考方案17】:

我写了一个转储函数,如果它没有覆盖 toString(),它基本上会打印出一个对象的公共成员。人们可以轻松地将其扩展为调用 getter。 Javadoc:

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

如果 Object 是 Iterable,则转储其所有组件。 如果 Object 或其超类之一覆盖 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();

【讨论】:

【参考方案18】:

我现在正好在做这个……

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

【讨论】:

【参考方案19】:
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()));
    

【讨论】:

【参考方案20】:

尝试根据需要覆盖 toString() 方法,以使元素打印结束。 所以打印的方法可以是这样的:

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

【讨论】:

这就是 OP 代码的作用。对toString 的调用是隐式的。【参考方案21】:

java 11 问题的解决方案是:

String separator = ", ";
String toPrint = list.stream().map(o -> String.valueOf(o)).collect(Collectors.joining(separator));

System.out.println(toPrint);

【讨论】:

【参考方案22】:

你可以试试:

2D(或更多)

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

一维

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

【讨论】:

【参考方案23】:
   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;
     
   

【讨论】:

以上是关于如何在 Java 中打印出 List 的所有元素?的主要内容,如果未能解决你的问题,请参考以下文章

给定一段Java 代码如下:要打印出list中存储的内容,以下语句正确的是()。(选择二项)

Java 如何打印出List中得值

python如何打印所有大于0的元素数据

打印出数组数组中元素的所有组合[重复]

打印出堆栈/队列的所有元素[关闭]

求助大神:java 中 现有一个list 要取出list中所有元素拼接成字符串以逗号隔开应该如何做?