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

这是我的打印代码…

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

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


当前回答

我写了一个转储函数,它基本上打印出对象的公共成员,如果它没有覆盖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]

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

    list.stream().map(x -> x.getName()).forEach(System.out::println);
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()));
    }

这取决于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);
   }
}