¿Cómo imprimir todos los elementos de una Lista en Java?

236

Estoy tratando de imprimir todos los elementos de un List, sin embargo, está imprimiendo el puntero delObject valor en lugar del valor.

Este es mi código de impresión ...

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

¿Podría alguien ayudarme por qué no está imprimiendo el valor de los elementos?

usuario1335361
fuente
3
¿Qué tipo declaraste Listser? Muéstranos cómo lo declaraste y lo instanciaste.
Makoto
debe llamar a toString y obtendrá una explicación de la clase o anular el método toString para el tipo que contiene la lista
L7ColWinters
Eso es lo que le está diciendo que imprima: necesita una cadena diferente u otra cadena legible.
Dave Newton
ArrayList <class> list = new ArrayList <class> ();
user1335361
44
Tenga en cuenta que hay una sintaxis más compacta que puede utilizar para obtener el mismo resultado: for (Object obj : list) {System.out.println(obj);}.
Aroth

Respuestas:

114

Aquí hay un ejemplo sobre cómo imprimir el componente de la lista:

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;
    }
}
Crazenezz
fuente
1
¿Cómo se relaciona la introducción de la Modelclase con la pregunta?
Karl Richter
44
Es solo una suposición, ya que no sé qué tipo de objeto dentro de la lista.
Crazenezz
477

Lo siguiente es compacto y evita el bucle en su código de ejemplo (y le da buenas comas):

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

Sin embargo, como otros han señalado, si no tiene implementados métodos toString () sensibles para los objetos dentro de la lista, obtendrá los punteros de objetos (códigos hash, de hecho) que está observando. Esto es cierto si están en una lista o no.

Holly Cummins
fuente
18
¿Qué pasa solo list.toString()?
Jaskey
22
Simplemente usando 'list.toString ()' no se imprimirán los elementos individuales, a menos que sea una implementación personalizada de la interfaz List que anula el comportamiento normal (para imprimir el nombre de la clase y un código hash, más o menos).
Holly Cummins
1
Si usan una clase personalizada y no anula toString, su solución también imprimirá su nombre de clase y código hash.
Jaskey
Se imprime como [valor1, valor2, valor3]. ¿Podemos imprimir como sin []?
muerto
En realidad, @Jaskey tiene razón: su respuesta es mejor. El Arraysmétodo es útil para las matrices, pero ahora no es necesario para las subclases de AbstractCollection.
Holly Cummins
100

Desde Java 8, List hereda un método "forEach" predeterminado que puede combinar con la referencia de método "System.out :: println" de esta manera:

list.forEach(System.out::println);
Karsten Hahn
fuente
2
@ Katja Hahn, ¿es posible agregar o anteponer alguna cadena a la printlnsalida?
gumkins
2
@ Gumkins, sí, puedes. Ejemplo: Arrays.stream (nueva cadena [] {"John", "Sansa", "Cersei"}). Map (s -> "Hi" + s + "!"). ForEach (System.out :: println) ;
Tiago Mussi
40
System.out.println(list);//toString() is easy and good enough for debugging.

toString()de AbstractCollection será lo suficientemente limpia y fácil de hacer eso . AbstractListes una subclase de AbstractCollection, por lo que no se necesita bucle ni toArray ().

Devuelve una representación de cadena de esta colección. La representación de cadena consiste en una lista de los elementos de la colección en el orden en que los devuelve su iterador, encerrados entre corchetes ("[]"). Los elementos adyacentes están separados por los caracteres "," (coma y espacio). Los elementos se convierten en cadenas como por String.valueOf (Object).

Si está utilizando algún objeto personalizado en su lista, por ejemplo, Estudiante, debe anular su toString() método (siempre es bueno anular este método) para tener una salida significativa

Vea el siguiente ejemplo:

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

salida:

[string1, string2]
[student Tom age:15, student Kate age:16]
Jaskey
fuente
Porque esta respuesta no es del todo correcta. Utiliza el polimorfismo sin darse cuenta. Aquí está la jerarquía de herencia real para list: List -> Collection -> Iterable -> Object. La clase que realmente hereda de AbstractCollection es ArrayList. Entonces, en este ejemplo, cuando toString()se llama encuentra la ArrayListimplementación que se define en AbstractCollection. Tenga en cuenta la jerarquía de herencia para ArrayList:ArrayList -> AbstractList -> AbstractCollection -> Collection -> Iterable -> Object
anon58192932
20

El enfoque de Java 8 Streams ...

list.stream().forEach(System.out::println);
Bradley D
fuente
misma respuesta que la de Katja Hahn
Karl Richter
No, no lo es. La mina aprovecha la corriente ().
Bradley D
@BradleyD, ¿qué ganancias se obtienen al agregar otra capa de llamadas a métodos allí?
Leon
15

Los objetos en la lista deben haberse toStringimplementado para que impriman algo significativo en la pantalla.

Aquí hay una prueba rápida para ver las diferencias:

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

Y cuando esto se ejecuta, los resultados impresos en la pantalla son:

t1 = Test$T1@19821f
t2 = 5

Como T1 no anula el método toString, su instancia t1 se imprime como algo que no es muy útil. Por otro lado, T2 anula a String, por lo que controlamos lo que imprime cuando se usa en E / S, y vemos algo un poco mejor en la pantalla.

K Mehta
fuente
11

Considere una List<String> stringListque se puede imprimir de muchas maneras usando construcciones 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)

¿En qué se diferencian estos enfoques entre sí?

Primer enfoque ( Iterable.forEach): el iterador de la colección generalmente se usa y está diseñado para fallar rápidamente, lo que significa que se lanzará ConcurrentModificationExceptionsi la colección subyacente se modifica estructuralmente durante la iteración. Como se menciona en el documento para ArrayList:

Una modificación estructural es cualquier operación que agrega o elimina uno o más elementos, o cambia el tamaño explícitamente de la matriz de respaldo; simplemente establecer el valor de un elemento no es una modificación estructural.

Por lo tanto, significa ArrayList.forEachque el valor está permitido sin ningún problema. Y en el caso de una recopilación simultánea, por ejemplo, ConcurrentLinkedQueueel iterador sería débilmente consistente, lo que significa que las acciones aprobadas forEachpueden realizar incluso cambios estructurales sin que se produzca una ConcurrentModificationExceptionexcepción. Pero aquí las modificaciones pueden o no ser visibles en esa iteración.

Segundo enfoque ( Stream.forEach): el orden no está definido. Aunque puede que no ocurra para secuencias secuenciales, la especificación no lo garantiza. También se requiere que la acción sea de naturaleza no interferente. Como se menciona en el documento :

El comportamiento de esta operación es explícitamente no determinista. Para las tuberías de flujo paralelo, esta operación no garantiza el respeto del orden de encuentro del flujo, ya que hacerlo sacrificaría el beneficio del paralelismo.

Tercer enfoque ( Stream.forEachOrdered): la acción se realizaría en el orden de encuentro de la secuencia. Por lo tanto, cuando el orden importa se usa forEachOrderedsin pensarlo dos veces. Como se menciona en el documento :

Realiza una acción para cada elemento de esta secuencia, en el orden de encuentro de la secuencia si la secuencia tiene un orden de encuentro definido.

Mientras itera sobre una colección sincronizada, el primer enfoque tomaría el bloqueo de la colección una vez y lo mantendría en todos los métodos de llamadas a la acción, pero en el caso de las transmisiones, usan el spliterator de la colección, que no se bloquea y se basa en las reglas establecidas de no -interferencia. En caso de que la copia de respaldo de la secuencia se modifique durante la iteración, unConcurrentModificationException , se generará un resultado incoherente.

Cuarto enfoque (paralelo Stream.forEach): como ya se mencionó, no hay garantía de respetar el orden de encuentro como se esperaba en el caso de flujos paralelos. Es posible que la acción se realice en diferentes hilos para diferentes elementos que nunca pueden ser el caso forEachOrdered.

Quinta Approach (Parallel Stream.forEachOrdered) - El forEachOrderedprocesará los elementos en el orden especificado por la fuente con independencia del hecho de si la corriente es secuencial o en paralelo. Por lo tanto, no tiene sentido usar esto con flujos paralelos.

akhil_mittal
fuente
9

Use String.join() por ejemplo:

System.out.print(String.join("\n", list)));
Lukasz Ochmanski
fuente
7

Me he enfrentado a problemas similares. Mi código:

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

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

Forma 1: imprimir una lista en un ciclo for

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

Modo 2: imprimir la lista en forEach, for loop

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

Camino 3: imprimir la lista en java 8

leaveDatesList.forEach(System.out::println);
Atequer Rahman
fuente
5
  1. No ha especificado qué tipo de elementos contiene la lista, si es un tipo de datos primitivo , puede imprimir los elementos.
  2. Pero si los elementos son objetos, como Kshitij Mehta mencionó, debe implementar (anular) el método "toString" dentro de ese objeto, si aún no está implementado, y dejar que devuelva algo que significa completo desde dentro del objeto, por ejemplo:

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

System.out.println(list); funciona para mi.

Aquí hay un ejemplo completo:

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

Se imprimirá [Hello, World].

jfmg
fuente
No es diferente de otras respuestas anteriores
Karl Richter
Di un ejemplo completo con las importaciones, la clase y el método principal que puede copiar y pegar y mostró el resultado. Por lo tanto, no hay razón para votar en mi opinión
jfmg
3

Para obtener una lista de la matriz de cadenas

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

Escribí una función de volcado, que básicamente imprime los miembros públicos de un objeto si no ha anulado aString (). Se podría expandir fácilmente para llamar a los captadores. Javadoc:

Vuelca un objeto dado en System.out, usando las siguientes reglas:

  • Si el objeto es Iterable, todos sus componentes se vuelcan.
  • Si el objeto o una de sus superclases anula toString (), se volcará "toString"
  • De lo contrario, el método se llama de forma recursiva para todos los miembros públicos del objeto

/**
 * 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();
}
Michael A. Schaffrath
fuente
2

Para bucle para imprimir el contenido de una lista:

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

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

Resultado:

Element : AA
Element : BB

Si desea imprimir en una sola línea (solo para información):

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

Resultado:

Elements : AA, BB
Théo Moulia
fuente
1
    list.stream().map(x -> x.getName()).forEach(System.out::println);
Ella
fuente
¿Qué tipo tiene xy cómo se relaciona con la pregunta del OP?
Karl Richter
1

Estoy trabajando en esto ahora ...

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);
wayneseymour
fuente
1

Depende de qué tipo de objetos almacenados en el List, y si tiene implementación para el toString()método. System.out.println(list)debe imprimir todos los tipos de objetos de Java estándar ( String, Long, Integeretc.). En el caso, si estamos utilizando tipos de objetos personalizados, entonces necesitamosoverride toString() método de nuestro objeto personalizado.

Ejemplo:

class Employee {
 private String name;
 private long id;

 @Override
 public String toString() {
   return "name: " + this.name() + 
           ", id: " + this.id();
 }  
}

Prueba:

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);
   }
}
Shravan Ramamurthy
fuente
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()));
    }
Alexander Mladzhov
fuente
0

intente anular el método toString () ya que desea que el elemento sea printend. entonces el método para imprimir puede ser este:

for(int i=0;i<list.size();i++){
    System.out.println(list.get(i).toString());
} 
riccardo_castellano
fuente
Eso es lo que hace el código del OP. La llamada a toStringes implícita.
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;
     }
   }
sharath
fuente