我试图打印出一个列表的所有元素,但它是打印对象的指针,而不是值。

这是我的打印代码…

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

有人能告诉我为什么它不打印元素的值吗?


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

You haven't specified what kind of elements the list contains, if it is a primitive data type then you can print out the elements. But if the elements are objects then as Kshitij Mehta mentioned you need to implement (override) the method "toString" within that object - if it is not already implemented - and let it return something meaning full from within the object, example: class Person { private String firstName; private String lastName; @Override public String toString() { return this.firstName + " " + this.lastName; } }

下面是一些关于打印list组件的例子:

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

下面的代码很紧凑,避免了示例代码中的循环(并提供了漂亮的逗号):

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

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

从Java 8开始,List继承了一个默认的“forEach”方法,你可以将它与方法引用“System”结合起来使用。输出::println”像这样:

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

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

将给定对象转储到系统。Out,使用以下规则: 如果对象是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();
}
System.out.println(list);//toString() is easy and good enough for debugging.

AbstractCollection的toString()将非常干净和容易做到这一点。AbstractList是AbstractCollection的子类,因此不需要for循环,也不需要toArray()。

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

如果您正在使用列表中的任何自定义对象,例如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]

System.out.println(列表);对我有用。

下面是一个完整的例子:

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]。

Java 8 Streams方法…

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

用于String数组的列表

list.forEach(s -> System.out.println(Arrays.toString((String[]) s )));
   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;
     }
   }
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()));
    }

尝试重写toString()方法,因为您希望元素将被打印。 打印的方法可以是这样的:

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

考虑一个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)- 通常使用集合的迭代器,它被设计为快速失败,这意味着如果底层集合在迭代期间被结构修改,它将抛出ConcurrentModificationException。正如在ArrayList的文档中提到的:

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

它的意思是数组列表。对于每个设置值都是允许的,没有任何问题。在并发收集的情况下,例如ConcurrentLinkedQueue,迭代器将是弱一致的,这意味着在forEach中传递的操作甚至可以在不抛出ConcurrentModificationExceptionexception的情况下进行结构更改。但是这里的修改可能在迭代中可见,也可能不可见。

第二种方法(Stream.forEach)- 顺序没有定义。虽然它可能不会出现在连续流中,但规范并不能保证它。此外,该行为还必须是不干涉性质的。如doc中所述:

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

第三种方法(Stream.forEachOrdered)- 该操作将按照流的遇到顺序执行。因此,每当顺序问题时,请使用forEachOrdered。正如文件中提到的:

在相遇中为此流的每个元素执行一个操作 如果流具有定义的遇到顺序,则为流的顺序。

当迭代一个同步集合时,第一种方法将获得集合的锁一次,并在所有对action方法的调用中保持它,但在流的情况下,他们使用集合的spliterator,它不锁,依赖于已经建立的不干扰规则。如果在迭代过程中修改了支持流的集合,则会抛出ConcurrentModificationException异常或可能出现不一致的结果。

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

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

或者你可以简单地使用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));

我现在正好在做这个…

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

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

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

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

这取决于List中存储的对象类型,以及它是否有toString()方法的实现。System.out.println(list)应该打印所有标准java对象类型(String, Long, Integer等)。在这种情况下,如果我们使用自定义对象类型,那么我们需要重写自定义对象的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);
   }
}

使用String.join () 例如:

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

java 11问题的解决方案是:

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

System.out.println(toPrint);

你可以试试:

2D(或以上) System.out.println (Arrays.deepToString (list.toArray ())); 1 d System.out.println (Arrays.toString (list.toArray ()))