Wie drucke ich alle Elemente einer Liste in Java aus?


235

Ich versuche, alle Elemente von a auszudrucken List, aber es wird Objecteher der Zeiger als der Wert gedruckt .

Dies ist mein Druckcode ...

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

Könnte mir bitte jemand helfen, warum der Wert der Elemente nicht gedruckt wird.


3
Welchen Typ haben Sie als solchen deklariert List? Zeigen Sie uns, wie Sie es deklariert und instanziiert haben.
Makoto

Sie müssen toString aufrufen und erhalten eine Erklärung der Klasse oder überschreiben die toString-Methode für den Typ, den die Liste enthält
L7ColWinters

Das ist es, was Sie zum Drucken sagen - Sie benötigen einen anderen als String oder eine andere lesbare Zeichenfolge.
Dave Newton

ArrayList <Klasse> list = new ArrayList <Klasse> ();
user1335361

4
Beachten Sie, dass es eine kompaktere Syntax gibt, mit der Sie dasselbe erreichen können : for (Object obj : list) {System.out.println(obj);}.
aroth

Antworten:


114

Hier ist ein Beispiel zum Ausdrucken der Listenkomponente:

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
Wie hängt die Einführung der ModelKlasse mit der Frage zusammen?
Karl Richter

4
Es ist nur eine Annahme, da ich nicht weiß, welche Art von Objekt in der Liste enthalten ist.
Crazenezz

475

Das Folgende ist kompakt und vermeidet die Schleife in Ihrem Beispielcode (und gibt Ihnen schöne Kommas):

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

Wie andere bereits betont haben, erhalten Sie die Objektzeiger (tatsächlich Hash-Codes), die Sie beobachten, wenn für die Objekte in der Liste keine sinnvollen toString () -Methoden implementiert sind. Dies gilt unabhängig davon, ob sie in einer Liste enthalten sind oder nicht.


18
Was ist nur mit list.toString().
Jaskey

22
Wenn Sie nur 'list.toString ()' verwenden, werden die einzelnen Elemente nicht gedruckt, es sei denn, es handelt sich um eine benutzerdefinierte Implementierung der List-Schnittstelle, die das normale Verhalten überschreibt (um den Klassennamen und einen Hash-Code mehr oder weniger zu drucken).
Holly Cummins

1
Wenn sie eine benutzerdefinierte Klasse verwenden und diese nicht überschreiben toString, druckt Ihre Lösung auch den Klassennamen und den Hashcode.
Jaskey

Es wird als [Wert1, Wert2, Wert3] gedruckt. Können wir wie ohne [] drucken?
Deadend

Eigentlich hat @Jaskey recht - ihre Antwort ist besser. Die ArraysMethode ist hilfreich für Arrays, wird jedoch jetzt nicht für Unterklassen von benötigt AbstractCollection.
Holly Cummins

100

Seit Java 8 erbt List eine Standardmethode "forEach", die Sie wie folgt mit der Methodenreferenz "System.out :: println" kombinieren können:

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

2
@Katja Hahn, ist es möglich, einen String an die printlnAusgabe anzuhängen oder voranzustellen ?
Gummis

2
@ Gummis, JA, du kannst. Beispiel: Arrays.stream (neuer String [] {"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()of AbstractCollection wird sauber und einfach genug sein, um das zu tun . AbstractListist eine Unterklasse von AbstractCollection, daher ist keine for-Schleife und kein toArray () erforderlich.

Gibt eine Zeichenfolgendarstellung dieser Sammlung zurück. Die Zeichenfolgendarstellung besteht aus einer Liste der Elemente der Sammlung in der Reihenfolge, in der sie vom Iterator zurückgegeben werden, in eckigen Klammern ("[]"). Benachbarte Elemente werden durch die Zeichen "," (Komma und Leerzeichen) getrennt. Elemente werden wie von String.valueOf (Object) in Strings konvertiert.

Wenn Sie ein benutzerdefiniertes Objekt in Ihrer Liste verwenden, z. B. Student, müssen Sie dessen toString()Methode überschreiben (es ist immer gut, diese Methode zu überschreiben), um eine aussagekräftige Ausgabe zu erhalten

Siehe das folgende Beispiel:

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

Ausgabe:

[string1, string2]
[student Tom age:15, student Kate age:16]

Weil diese Antwort nicht ganz richtig ist. Es verwendet Polymorphismus, ohne es zu merken. Hier ist die tatsächliche Vererbungshierarchie für list: List -> Collection -> Iterable -> Object. Die Klasse, die tatsächlich von AbstractCollection erbt, ist ArrayList. Wenn in diesem Beispiel toString()aufgerufen wird, findet es die ArrayListImplementierung, die in definiert ist AbstractCollection. Beachten Sie die Vererbungshierarchie für ArrayList:ArrayList -> AbstractList -> AbstractCollection -> Collection -> Iterable -> Object
anon58192932

21

Der Java 8 Streams Ansatz ...

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

gleiche Antwort wie Katja Hahns
Karl Richter

Nein, ist es nicht. Mine nutzt stream ().
Bradley D

@BradleyD Welche Gewinne werden erzielt, wenn dort eine weitere Ebene von Methodenaufrufen hinzugefügt wird?
Leon

15

Die Objekte in der Liste müssen toStringimplementiert sein, damit sie etwas drucken können, das für den Bildschirm von Bedeutung ist.

Hier ist ein kurzer Test, um die Unterschiede zu erkennen:

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

Wenn dies ausgeführt wird, werden folgende Ergebnisse auf dem Bildschirm gedruckt:

t1 = Test$T1@19821f
t2 = 5

Da T1 die toString-Methode nicht überschreibt, wird ihre Instanz t1 als etwas ausgegeben, das nicht sehr nützlich ist. Auf der anderen Seite überschreibt T2String, sodass wir steuern, was gedruckt wird, wenn es in E / A verwendet wird, und auf dem Bildschirm etwas Besseres sehen.


11

Stellen Sie sich eine vor, List<String> stringListdie mit Java 8- Konstrukten auf viele Arten gedruckt werden kann :

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)

Wie unterscheiden sich diese Ansätze voneinander?

Erster Ansatz ( Iterable.forEach) - Der Iterator der Sammlung wird im Allgemeinen verwendet und ist ausfallsicher ausgelegt. Dies bedeutet, dass er ausgelöst wird, ConcurrentModificationExceptionwenn die zugrunde liegende Sammlung während der Iteration strukturell geändert wird. Wie im Dokument erwähnt für ArrayList:

Eine strukturelle Änderung ist eine Operation, die ein oder mehrere Elemente hinzufügt oder löscht oder die Größe des Hintergrundarrays explizit ändert. Das bloße Festlegen des Werts eines Elements ist keine strukturelle Änderung.

Dies bedeutet, dass das ArrayList.forEachEinstellen des Werts ohne Probleme zulässig ist. Und im Falle einer gleichzeitigen Erfassung wäre beispielsweise ConcurrentLinkedQueueder Iterator schwach konsistent, was bedeutet, dass die übergebenen Aktionen ausnahmslos forEachsogar strukturelle Änderungen vornehmen dürfen ConcurrentModificationException. Aber hier können die Änderungen in dieser Iteration sichtbar sein oder nicht.

Zweiter Ansatz ( Stream.forEach) - Die Reihenfolge ist undefiniert. Es kann zwar nicht für sequentielle Streams auftreten, aber die Spezifikation garantiert dies nicht. Außerdem muss die Aktion nicht störend wirken. Wie in doc erwähnt :

Das Verhalten dieser Operation ist explizit nicht deterministisch. Bei parallelen Stream-Pipelines garantiert diese Operation nicht, dass die Aufeinanderreihenfolge des Streams eingehalten wird, da dies den Vorteil der Parallelität beeinträchtigen würde.

Dritter Ansatz ( Stream.forEachOrdered) - Die Aktion wird in der Reihenfolge der Begegnung des Streams ausgeführt. Also, wann immer es auf Bestellung ankommt, forEachOrderedohne einen zweiten Gedanken zu verwenden. Wie im Dokument erwähnt :

Führt eine Aktion für jedes Element dieses Streams in der Begegnungsreihenfolge des Streams aus, wenn der Stream eine definierte Begegnungsreihenfolge hat.

Während der Iteration über eine synchronisierte Sammlung würde der erste Ansatz die Sperre der Sammlung einmal aufheben und sie über alle Aufrufe der Aktionsmethode hinweg halten. Bei Streams wird jedoch der Spliterator der Sammlung verwendet, der nicht sperrt und sich auf die bereits festgelegten Regeln von non stützt -Interferenz. Wenn das Sichern der Sammlung während der Iteration geändert wird, wird ein ConcurrentModificationExceptionWert ausgelöst oder es kann zu einem inkonsistenten Ergebnis kommen.

Vierter Ansatz (parallel Stream.forEach) - Wie bereits erwähnt, keine Garantie, die bei parallelen Streams erwartete Reihenfolge der Begegnungen einzuhalten. Es ist möglich, dass Aktionen in verschiedenen Threads für verschiedene Elemente ausgeführt werden, was bei niemals der Fall sein kann forEachOrdered.

Fünfter Ansatz (parallel Stream.forEachOrdered) - Der forEachOrderedverarbeitet die Elemente in der von der Quelle angegebenen Reihenfolge, unabhängig davon, ob der Stream sequentiell oder parallel ist. Es macht also keinen Sinn, dies mit parallelen Streams zu verwenden.




7

Ich habe ähnliche Probleme gehabt. Mein Code:

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

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

Weg 1: Drucken einer Liste in einer for-Schleife

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

Weg 2: Drucken der Liste in einer forEach, for-Schleife

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

Weg 3: Drucken der Liste in Java 8

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

5
  1. Sie haben nicht angegeben, welche Art von Elementen die Liste enthält. Wenn es sich um einen primitiven Datentyp handelt , können Sie die Elemente ausdrucken.
  2. Wenn es sich bei den Elementen jedoch um Objekte handelt, müssen Sie, wie Kshitij Mehta erwähnt hat, die Methode "toString" in diesem Objekt implementieren (überschreiben) - sofern sie noch nicht implementiert ist - und sie aus dem Objekt eine vollständige Bedeutung zurückgeben lassen. Beispiel:

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

3

System.out.println(list); funktioniert bei mir.

Hier ist ein vollständiges Beispiel:

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

Es wird gedruckt [Hello, World].


Nicht anders als andere, frühere Antworten
Karl Richter

Ich gab ein vollständiges Beispiel mit Importen, Klassen und Hauptmethoden, die Sie kopieren und einfügen können, und zeigte das Ergebnis. Daher kein Grund, es meiner Meinung nach abzustimmen
jfmg

3

Für eine Liste von Array von String

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

2

Ich habe eine Dump-Funktion geschrieben, die grundsätzlich die öffentlichen Mitglieder eines Objekts druckt, wenn es nicht zu String () überschrieben wurde. Man könnte es leicht erweitern, um Getter zu nennen. Javadoc:

Gibt ein bestimmtes Objekt nach den folgenden Regeln an System.out aus:

  • Wenn das Objekt iterierbar ist, werden alle seine Komponenten ausgegeben.
  • Wenn das Objekt oder eine seiner Oberklassen toString () überschreibt, wird der "toString" ausgegeben
  • Andernfalls wird die Methode für alle öffentlichen Mitglieder des Objekts rekursiv aufgerufen

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

For-Schleife zum Drucken des Inhalts einer Liste:

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

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

Ergebnis:

Element : AA
Element : BB

Wenn Sie in einer einzelnen Zeile drucken möchten (nur zur Information):

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

Ergebnis:

Elements : AA, BB

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

Welcher Typ hat xund in welcher Beziehung steht er zur Frage des OP?
Karl Richter

1

Ich arbeite gerade daran ...

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

Dies hängt davon ab, welche Art von Objekten in der Methode gespeichert Listist und ob eine Implementierung für die toString()Methode vorhanden ist. System.out.println(list)drucken alle Standard - Java - Objekttypen sollten ( String, Long, Integerusw.). Wenn wir benutzerdefinierte Objekttypen verwenden, müssen wir die override toString()Methode unseres benutzerdefinierten Objekts verwenden.

Beispiel:

class Employee {
 private String name;
 private long id;

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

Prüfung:

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

Versuchen Sie, die toString () -Methode so zu überschreiben, wie Sie möchten, dass das Element gedruckt wird. Die Druckmethode kann also folgende sein:

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

Das macht der OP-Code. Der Aufruf von toStringist implizit.
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;
     }
   }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.