Como imprimir todos os elementos de uma lista em Java?

236

Estou tentando imprimir todos os elementos de a List, no entanto, ele está imprimindo o ponteiro do Objectvalor e não do valor.

Este é o meu código de impressão ...

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

Alguém poderia me ajudar por que não está imprimindo o valor dos elementos.

user1335361
fonte
3
Que tipo você declarou Listser? Mostre-nos como você o declarou e instanciaram.
Makoto
você tem que chamar toString e você vai obter uma explicação da classe ou substituir o método toString para o tipo que a lista contém
L7ColWinters
É isso que você está dizendo para imprimir - você precisa de um toString diferente ou outra string legível.
31812 Dave
ArrayList <class> lista = nova ArrayList <class> ();
precisa saber é o seguinte
4
Note-se que há uma sintaxe mais compacta que você pode usar para realizar a mesma coisa: for (Object obj : list) {System.out.println(obj);}.
Aroth 16/04

Respostas:

114

Aqui está um exemplo de como imprimir o componente da 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
fonte
1
Como a introdução da Modelturma está relacionada à pergunta?
Karl Richter
4
É apenas uma suposição, já que eu não sei que tipo de objeto dentro da lista.
Crazenezz
477

O seguinte é compacto e evita o loop no seu código de exemplo (e fornece boas vírgulas):

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

No entanto, como outros salientaram, se você não possui métodos sensíveis toString () implementados para os objetos dentro da lista, receberá os ponteiros do objeto (na verdade, códigos de hash) que está observando. Isso é verdade se eles estão em uma lista ou não.

Holly Cummins
fonte
18
Que tal apenas list.toString().
Jaskey
22
O simples uso de 'list.toString ()' não imprimirá os elementos individuais, a menos que seja uma implementação personalizada da interface List que substitua o comportamento normal (para imprimir o nome da classe e um código de hash, mais ou menos).
Holly Cummins
1
Se eles usarem classe personalizada e não substituir toString, sua solução também imprimirá seu nome de classe e código de hash.
Jaskey
Imprime como [valor1, valor2, valor3]. Podemos imprimir como sem []?
deadend
Na verdade, @Jaskey está certo - a resposta é melhor. O Arraysmétodo é útil para matrizes, mas agora não é necessário para subclasses de AbstractCollection.
Holly Cummins
100

Desde o Java 8, a List herda um método "forEach" padrão, que você pode combinar com a referência do método "System.out :: println", assim:

list.forEach(System.out::println);
Karsten Hahn
fonte
2
@ Katja Hahn, é possível acrescentar ou acrescentar alguma string à printlnsaída?
gumkins
2
@ Gumkins, sim, você pode. Exemplo: Arrays.stream (nova String [] {"John", "Sansa", "Cersei"}). Map (s -> "Oi" + s + "!"). ForEach (System.out :: println) ;
Tiago Mussi
40
System.out.println(list);//toString() is easy and good enough for debugging.

toString()de AbstractCollection será limpo e fácil o suficiente para fazer isso . AbstractListé uma subclasse de AbstractCollection, portanto , não é necessário fazer loop e nem toArray ().

Retorna uma representação de sequência desta coleção. A representação de cadeia consiste em uma lista dos elementos da coleção na ordem em que são retornados por seu iterador, entre colchetes ("[]"). Os elementos adjacentes são separados pelos caracteres "," (vírgula e espaço). Os elementos são convertidos em seqüências de caracteres como por String.valueOf (Object).

Se você estiver usando qualquer objeto personalizado em sua lista, diga Aluno, precisará substituir seu toString()método (é sempre bom substituir esse método) para obter uma saída significativa

Veja o exemplo abaixo:

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

resultado:

[string1, string2]
[student Tom age:15, student Kate age:16]
Jaskey
fonte
Porque esta resposta não está totalmente correta. Está usando polimorfismo sem perceber. Aqui está a hierarquia de herança real para list: List -> Collection -> Iterable -> Object. A classe que realmente herda de AbstractCollection é ArrayList. Portanto, neste exemplo, quando toString()é chamado, encontra a ArrayListimplementação definida em AbstractCollection. Observe a hierarquia de herança para ArrayList:ArrayList -> AbstractList -> AbstractCollection -> Collection -> Iterable -> Object
anon58192932
20

A abordagem do Java 8 Streams ...

list.stream().forEach(System.out::println);
Bradley D
fonte
mesma resposta que a de Katja Hahn
Karl Richter
Não, não é. A mina aproveita o fluxo ().
Bradley D
@BradleyD, que ganhos são obtidos com a adição de outra camada de método?
Leon
15

Os objetos na lista devem ter sido toStringimplementados para que eles imprimam algo significativo na tela.

Aqui está um teste rápido para ver as diferenças:

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

E quando isso é executado, os resultados impressos na tela são:

t1 = Test$T1@19821f
t2 = 5

Como T1 não substitui o método toString, sua instância t1 é impressa como algo que não é muito útil. Por outro lado, o T2 substitui o ToString, por isso controlamos o que é impresso quando usado em E / S e vemos algo um pouco melhor na tela.

K Mehta
fonte
11

Considere um List<String> stringListque pode ser impresso de várias maneiras usando construções 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)

Como essas abordagens são diferentes umas das outras?

Primeira abordagem ( Iterable.forEach) - o iterador da coleção geralmente é usado e é projetado para ser rápido, o que significa que será lançado ConcurrentModificationExceptionse a coleção subjacente for estruturalmente modificada durante a iteração. Conforme mencionado no documento para ArrayList:

Uma modificação estrutural é qualquer operação que adiciona ou exclui um ou mais elementos ou redimensiona explicitamente a matriz de suporte; apenas definir o valor de um elemento não é uma modificação estrutural.

Então, isso significa ArrayList.forEachque a definição do valor é permitida sem nenhum problema. E no caso de coleta simultânea, por exemplo, ConcurrentLinkedQueueo iterador seria fracamente consistente, o que significa que as ações transmitidas forEachpodem fazer alterações estruturais mesmo sem que ConcurrentModificationExceptionsejam lançadas exceções. Mas aqui as modificações podem ou não ser visíveis nessa iteração.

Segunda abordagem ( Stream.forEach) - o pedido não está definido. Embora possa não ocorrer para fluxos sequenciais, mas a especificação não garante isso. Também é necessário que a ação seja de natureza não interferente. Como mencionado no doc :

O comportamento desta operação é explicitamente não determinístico. Para pipelines de fluxo paralelo, esta operação não garante o respeito à ordem de encontro do fluxo, pois isso sacrificaria o benefício do paralelismo.

Terceira abordagem ( Stream.forEachOrdered) - a ação seria executada na ordem de encontro do fluxo. Portanto, sempre que a ordem importa, use forEachOrderedsem pensar duas vezes. Conforme mencionado no documento :

Executa uma ação para cada elemento desse fluxo, na ordem de encontro do fluxo, se o fluxo tiver uma ordem de encontro definida.

Ao iterar sobre uma coleção sincronizada, a primeira abordagem retira o bloqueio da coleção uma vez e o mantém em todas as chamadas para o método de ação, mas no caso de fluxos, eles usam o spliterator da coleção, que não bloqueia e depende das regras já estabelecidas de -interferência. Caso a coleta de backup do fluxo seja modificada durante a iteração ConcurrentModificationException, será lançado um resultado inconsistente.

Quarta Abordagem (Paralela Stream.forEach) - Como já mencionado, não há garantia de respeitar a ordem do encontro como esperado no caso de fluxos paralelos. É possível que a ação seja executada em um encadeamento diferente para diferentes elementos que nunca podem ser o caso forEachOrdered.

Quinto Approach (paralela Stream.forEachOrdered) - A forEachOrderedvai processar os elementos na ordem especificada pela fonte, independentemente do facto de se transmitir é sequencial ou paralelo. Portanto, não faz sentido usar isso com fluxos paralelos.

akhil_mittal
fonte
9

Use String.join() por exemplo:

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

Eu enfrentei problemas semelhantes. Meu código:

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

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

Caminho 1: imprimir uma lista em um loop for

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

Caminho 2: imprimindo a lista em um loop forEach, for

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

Caminho 3: imprimindo a lista em java 8

leaveDatesList.forEach(System.out::println);
Atequer Rahman
fonte
5
  1. Você não especificou que tipo de elementos a lista contém; se for um tipo de dados primitivo , poderá imprimir os elementos.
  2. Mas se os elementos são objetos, como Kshitij Mehta mencionou, é necessário implementar (substituir) o método "toString" dentro desse objeto - se ainda não estiver implementado - e permitir que ele retorne algo significativo dentro do objeto, por exemplo:

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

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

Aqui está um exemplo 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);
     }
}

Ele será impresso [Hello, World].

jfmg
fonte
Não diferente de outras, respostas anteriores
Karl Richter
Dei um exemplo completo com importações, classe e método principal, que você pode copiar e colar e mostrou o resultado. Portanto, não há razão para votá-lo na minha opinião
jfmg 17/11
3

Para uma lista da matriz de String

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

Eu escrevi uma função de despejo, que basicamente imprime os membros públicos de um objeto se ele não substituiu toString (). Pode-se expandi-lo facilmente para chamar getters. Javadoc:

Despeja um determinado objeto para System.out, usando as seguintes regras:

  • Se o objeto for iterável, todos os seus componentes serão descartados.
  • Se o objeto ou uma de suas superclasses substituir toString (), o "toString" será despejado
  • Senão, o método é chamado recursivamente para todos os membros públicos do Object

/**
 * 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
fonte
2

For loop para imprimir o conteúdo de uma 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

Se você deseja imprimir em uma única linha (apenas para obter informações):

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

Resultado:

Elements : AA, BB
Théo Moulia
fonte
1
    list.stream().map(x -> x.getName()).forEach(System.out::println);
Ella
fonte
Que tipo tem xe como está relacionado à pergunta do OP?
Karl Richter
1

Eu estou trabalhando nisso agora ...

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
fonte
1

Depende de que tipo de objetos armazenados no Liste se tem implementação para o toString()método. System.out.println(list)deve imprimir todos os tipos de objetos Java padrão ( String, Long, Integeretc). No caso, se estivermos usando tipos de objetos personalizados, precisamosoverride toString() método do nosso objeto personalizado.

Exemplo:

class Employee {
 private String name;
 private long id;

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

Teste:

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
fonte
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
fonte
0

tente substituir o método toString () como desejar que o elemento seja impresso. então o método para imprimir pode ser este:

for(int i=0;i<list.size();i++){
    System.out.println(list.get(i).toString());
} 
riccardo_castellano
fonte
É isso que o código do OP faz. A chamada para toStringestá 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
fonte