如何在 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 或其他可读的字符串。
ArrayListfor (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()
将干净且容易做到这一点。 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]
【讨论】:
因为这个答案并不完全正确。它在没有意识到的情况下使用多态性。这是list
的实际继承层次结构:List -> Collection -> Iterable -> Object
。实际上从 AbstractCollection 继承的类是ArrayList
。所以在这个例子中,当toString()
被调用时,它会找到ArrayList
在AbstractCollection
中定义的实现。注意ArrayList
的继承层次结构:ArrayList -> AbstractList -> AbstractCollection -> Collection -> Iterable -> 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<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
)-
通常使用集合的迭代器,它被设计为fail-fast,这意味着如果底层集合在迭代期间被结构修改,它将抛出ConcurrentModificationException
。正如doc 中提到的ArrayList
:
结构修改是添加或删除一个或 更多元素,或显式调整后备数组的大小;只是设置 元素的值不是结构修改。
所以这意味着对于ArrayList.forEach
,设置该值是允许的,没有任何问题。在并发收集的情况下,例如ConcurrentLinkedQueue
迭代器将是 weakly-consistent,这意味着在 forEach
中传递的操作甚至可以进行结构更改,而不会引发 ConcurrentModificationException
exception。但这里的修改可能在该迭代中可见也可能不可见。
第二种方法 (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 对象类型(String
、Long
、Integer
等)。如果我们使用自定义对象类型,那么我们需要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);
【讨论】:
【参考方案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 的所有元素?的主要内容,如果未能解决你的问题,请参考以下文章