Bagaimana cara mencetak semua elemen Daftar di Jawa?


236

Saya mencoba untuk mencetak semua elemen dari a List, tetapi mencetak pointer Objectdaripada nilai.

Ini adalah kode pencetakan saya ...

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

Adakah yang bisa membantu saya mengapa tidak mencetak nilai elemen.


3
Apa jenis yang Anda nyatakan Listsebagai? Tunjukkan kepada kami bagaimana Anda mendeklarasikan dan membuat instance itu.
Makoto

Anda harus memanggil toString dan Anda akan mendapatkan penjelasan tentang kelas atau mengganti metode toString untuk jenis yang berisi daftar
L7ColWinters

Itulah yang Anda katakan untuk dicetak - Anda memerlukan toString yang berbeda atau string yang dapat dibaca lainnya.
Dave Newton

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

4
Perhatikan bahwa ada sintaks lebih kompak yang dapat digunakan untuk mencapai hal yang sama: for (Object obj : list) {System.out.println(obj);}.
Agustus

Jawaban:


114

Berikut adalah beberapa contoh tentang cara mencetak komponen daftar:

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
Bagaimana pengantar Modelkelas terkait dengan pertanyaan?
Karl Richter

4
Itu hanya asumsi, karena saya tidak tahu jenis objek apa di dalam daftar.
Crazenezz

477

Berikut ini adalah kompak dan menghindari loop dalam kode contoh Anda (dan memberi Anda koma bagus):

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

Namun, seperti yang orang lain tunjukkan, jika Anda tidak memiliki metode toString () yang masuk akal diterapkan untuk objek di dalam daftar, Anda akan mendapatkan pointer objek (kode hash, pada kenyataannya) yang Anda amati. Ini benar apakah mereka ada dalam daftar atau tidak.


18
Tentang apa saja list.toString().
Jaskey

22
Hanya menggunakan 'list.toString ()' tidak akan mencetak elemen individu, kecuali itu adalah implementasi kustom dari antarmuka Daftar yang mengesampingkan perilaku normal (untuk mencetak nama kelas dan kode hash, lebih atau kurang).
Holly Cummins

1
Jika mereka menggunakan kelas khusus dan tidak menimpa toString, solusi Anda juga akan mencetak nama kelas dan kode hash.
Jaskey

Mencetak sebagai [value1, value2, value3]. Bisakah kita mencetak tanpa []?
deadend

Sebenarnya, @Jaskey benar - jawaban mereka lebih baik. The Arraysmetode adalah membantu untuk array, tapi tidak sekarang dibutuhkan untuk subclass dari AbstractCollection.
Holly Cummins

100

Sejak Java 8, Daftar mewarisi metode "forEach" default yang dapat Anda gabungkan dengan referensi metode "System.out :: println" seperti ini:

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

2
@Katja Hahn, apakah mungkin untuk menambahkan atau menambahkan beberapa string ke printlnoutput?
gumkins

2
@ gumkins, YA, Anda bisa. Contoh: Arrays.stream (String baru [] {"John", "Sansa", "Cersei"}). Map (s -> "Hai" + s + "!"). ForEach (System.out :: println) ;
Tiago Mussi

40
System.out.println(list);//toString() is easy and good enough for debugging.

toString()dari AbstractCollection akan menjadi bersih dan cukup mudah untuk melakukan itu . AbstractListadalah subclass dari AbstractCollection, jadi tidak perlu untuk loop dan tidak diperlukan toArray ().

Mengembalikan representasi string dari koleksi ini. Representasi string terdiri dari daftar elemen koleksi dalam urutan mereka dikembalikan oleh iteratornya, dilampirkan dalam tanda kurung siku ("[]"). Elemen yang berdekatan dipisahkan oleh karakter "," (koma dan spasi). Elemen dikonversikan ke string seperti oleh String.valueOf (Object).

Jika Anda menggunakan objek kustom apa pun dalam daftar Anda, katakanlah Student, Anda perlu mengganti toString()metodenya (selalu baik untuk mengganti metode ini) untuk mendapatkan hasil yang bermakna

Lihat contoh di bawah ini:

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

keluaran:

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

Karena jawaban ini tidak sepenuhnya benar. Itu menggunakan polimorfisme tanpa menyadarinya. Berikut hirarki warisan sebenarnya untuk list: List -> Collection -> Iterable -> Object. Kelas yang sebenarnya diwarisi dari AbstractCollection adalah ArrayList. Jadi, dalam contoh ini ketika toString()dipanggil menemukan ArrayListimplementasi yang didefinisikan dalam AbstractCollection. Perhatikan hierarki warisan untuk ArrayList:ArrayList -> AbstractList -> AbstractCollection -> Collection -> Iterable -> Object
anon58192932

20

Pendekatan Java 8 Streaming ...

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

jawaban yang sama dengan jawaban Katja Hahn
Karl Richter

Bukan itu. Aliran pengungkit tambang ().
Bradley D

@BradleyD keuntungan apa yang direalisasikan dengan menambahkan lapisan metode panggilan lain di sana?
Leon

15

Objek dalam daftar harus toStringdiimplementasikan agar mereka dapat mencetak sesuatu yang berarti untuk disaring.

Inilah tes cepat untuk melihat perbedaannya:

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

Dan ketika ini dijalankan, hasil yang dicetak ke layar adalah:

t1 = Test$T1@19821f
t2 = 5

Karena T1 tidak mengesampingkan metode toString, contohnya t1 mencetak sebagai sesuatu yang tidak terlalu berguna. Di sisi lain, T2 menggantikan toString, jadi kami mengontrol apa yang dicetaknya saat digunakan di I / O, dan kami melihat sesuatu yang sedikit lebih baik di layar.


11

Pertimbangkan List<String> stringListyang dapat dicetak dalam banyak cara menggunakan konstruksi 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)

Bagaimana pendekatan ini berbeda satu sama lain?

Pendekatan Pertama ( Iterable.forEach) - Iterator koleksi umumnya digunakan dan yang dirancang untuk gagal-cepat yang berarti akan dibuang ConcurrentModificationExceptionjika koleksi yang mendasarinya secara struktural dimodifikasi selama iterasi. Sebagaimana disebutkan dalam dokumen untuk ArrayList:

Modifikasi struktural adalah setiap operasi yang menambah atau menghapus satu atau lebih elemen, atau secara eksplisit mengubah ukuran backing array; hanya pengaturan nilai suatu elemen bukanlah modifikasi struktural.

Jadi itu berarti untuk ArrayList.forEachmenetapkan nilai diperbolehkan tanpa masalah. Dan dalam kasus pengumpulan konkuren misalnya ConcurrentLinkedQueueiterator akan lemah-konsisten yang berarti tindakan forEachyang dilakukan diperbolehkan untuk membuat bahkan perubahan struktural tanpa ConcurrentModificationExceptionkecuali dilemparkan. Tapi di sini modifikasi mungkin atau mungkin tidak terlihat dalam iterasi itu.

Pendekatan Kedua ( Stream.forEach) - Pesanan tidak ditentukan. Meskipun mungkin tidak terjadi untuk aliran berurutan tetapi spesifikasi tidak menjaminnya. Juga tindakan tersebut dituntut untuk tidak mengganggu. Seperti disebutkan dalam dokumen :

Perilaku operasi ini secara eksplisit tidak deterministik. Untuk pipa aliran paralel, operasi ini tidak menjamin untuk menghormati urutan pertemuan arus, karena hal itu akan mengorbankan manfaat paralelisme.

Pendekatan Ketiga ( Stream.forEachOrdered) - Tindakan akan dilakukan dalam urutan pertemuan aliran. Jadi, kapan pun pesanan penting digunakan forEachOrderedtanpa pikir panjang. Sebagaimana disebutkan dalam dokumen :

Melakukan tindakan untuk setiap elemen aliran ini, dalam urutan pertemuan aliran jika aliran memiliki urutan pertemuan yang ditentukan.

Sementara iterasi pada koleksi yang disinkronkan , pendekatan pertama akan mengambil kunci koleksi sekali dan akan menahannya di semua panggilan untuk metode tindakan, tetapi dalam kasus stream mereka menggunakan kumpulan spliterator, yang tidak mengunci dan bergantung pada aturan non -gangguan. Dalam kasus pengumpulan dukungan, aliran dimodifikasi selama iterasi yang ConcurrentModificationExceptionakan dilempar atau hasil yang tidak konsisten dapat terjadi.

Pendekatan Keempat (Paralel Stream.forEach) - Seperti yang telah disebutkan tidak ada jaminan untuk menghormati urutan pertemuan seperti yang diharapkan dalam kasus aliran paralel. Ada kemungkinan bahwa tindakan dilakukan dalam utas yang berbeda untuk elemen yang berbeda yang tidak akan pernah terjadi forEachOrdered.

Pendekatan Kelima (Paralel Stream.forEachOrdered) - Proses forEachOrderedakan elemen dalam urutan yang ditentukan oleh sumber terlepas dari fakta apakah aliran berurutan atau paralel. Jadi tidak masuk akal untuk menggunakan ini dengan aliran paralel.




7

Saya telah menghadapi masalah yang sama. Kode saya:

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

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

Cara 1: mencetak daftar dalam for loop

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

Cara 2: mencetak daftar di forEach, untuk loop

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

Cara 3: mencetak daftar di java 8

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

5
  1. Anda belum menentukan elemen apa saja yang terdapat dalam daftar, jika itu adalah tipe data primitif maka Anda dapat mencetak elemen tersebut.
  2. Tetapi jika elemen-elemennya adalah objek maka seperti yang disebutkan oleh Kshitij Mehta, Anda perlu mengimplementasikan (override) metode "toString" di dalam objek itu - jika belum diimplementasikan - dan membiarkannya mengembalikan sesuatu yang penuh makna dari dalam objek, contoh:

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

3

System.out.println(list); bekerja untukku.

Ini adalah contoh lengkapnya:

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

Itu akan mencetak [Hello, World].


Tidak berbeda dengan yang lain, jawaban sebelumnya
Karl Richter

Saya memberikan contoh lengkap dengan impor, kelas dan metode utama yang dapat Anda salin dan tempel dan tunjukkan hasilnya. Karena itu, tidak ada alasan untuk memilihnya menurut pendapat saya
jfmg

3

Untuk daftar array String

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

2

Saya menulis fungsi dump, yang pada dasarnya mencetak anggota publik dari suatu objek jika belum menimpa toString (). Seseorang dapat dengan mudah mengembangkannya untuk memanggil getter. Javadoc:

Membuang Objek yang diberikan ke System.out, menggunakan aturan berikut:

  • Jika Objek itu Iterable, semua komponennya dibuang.
  • Jika Objek atau salah satu dari superclasses menimpa toString (), "toString" dibuang
  • Jika tidak, metode ini disebut secara rekursif untuk semua anggota publik Obyek

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

Agar loop mencetak konten daftar:

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

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

Hasil:

Element : AA
Element : BB

Jika Anda ingin mencetak dalam satu baris (hanya untuk informasi):

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

Hasil:

Elements : AA, BB

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

Jenis apa yang dimiliki xdan bagaimana hubungannya dengan pertanyaan OP?
Karl Richter

1

Saya kebetulan sedang mengerjakan ini sekarang ...

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

Itu tergantung pada jenis objek yang disimpan di List, dan apakah itu memiliki implementasi untuk toString()metode. System.out.println(list)harus mencetak semua jenis java objek standar ( String, Long, Integerdll). Dalam hal ini, jika kita menggunakan tipe objek kustom, maka kita perlu override toString()metode objek kustom kita.

Contoh:

class Employee {
 private String name;
 private long id;

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

Uji:

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

cobalah untuk mengganti metode toString () seperti yang Anda inginkan bahwa elemen akan printend. jadi metode untuk mencetak bisa seperti ini:

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

Itulah yang dilakukan kode OP. Panggilan ke toStringtersirat.
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;
     }
   }
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.