¿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?


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

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.


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

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]

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

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.


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.




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

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

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


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

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

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

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

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

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

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

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

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;
     }
   }
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.