Java'da bir Listenin tüm öğelerini nasıl yazdırabilirim?


236

Ben tüm unsurları yazdırmaya çalışıyorum List, ancak bu Objectdeğer yerine işaretçi yazdırıyor .

Bu benim yazdırma kodum ...

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

Herkes neden öğelerin değerini yazdırmıyor bana yardımcı olabilir.


3
Ne tür ilan ettiniz List? Bize nasıl beyan ettiğinizi ve somutlaştırdığınızı gösterin.
Makoto

toString aramak ve sınıfın bir açıklama almak youll veya liste içerdiğini türü için toString yöntemi geçersiz var
L7ColWinters

Yazdırmak için söylediğiniz şey budur - İplik veya başka bir okunabilir dizeye ihtiyacınız vardır.
Dave Newton

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

4
Eğer aynı şeyi gerçekleştirmek için kullanabileceğiniz bir daha kompakt bir yazım var unutmayın: for (Object obj : list) {System.out.println(obj);}.
aroth

Yanıtlar:


114

Liste bileşenini yazdırmayla ilgili bazı örnekler:

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
ModelSınıfın tanıtımı soru ile nasıl ilişkilidir?
Karl Richter

4
Bu sadece bir varsayım, çünkü listenin içinde ne tür bir Nesne olduğunu bilmiyorum.
Crazenezz

477

Aşağıdakiler kompakttır ve örnek kodunuzdaki döngüyü önler (ve size güzel virgüller verir):

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

Ancak, diğerlerinin de belirttiği gibi, listedeki nesneler için uygulanan toString () yöntemlerine duyarlı değilseniz, gözlemlediğiniz nesne işaretleyicilerini (aslında hash kodları) alırsınız. Bir listede olsalar da olmasalar da bu doğrudur.


18
Sadece ne olacak list.toString().
Jaskey

22
'List.toString ()' işlevini kullanmak, normal davranışı geçersiz kılan (sınıf adını ve karma kodunu, daha fazla veya daha az yazdırmak için) List arabiriminin özel bir uygulaması değilse, tek tek öğeleri yazdırmaz.
Holly Cummins

1
Özel sınıf kullanıyorlarsa ve geçersiz kılmazlarsa toString, çözümünüz sınıf adını ve karma kodunu da yazdırır.
Jaskey

[Değer1, değer2, değer3] olarak yazdırır. [] Olmadan olduğu gibi yazdırabilir miyiz?
deadend

Aslında, @Jaskey haklı - cevapları daha iyi. ArraysYöntem diziler için yararlı, ancak şimdi alt sınıfları için gerekli değildir AbstractCollection.
Holly Cummins

100

Java 8'den bu yana, List "System.out :: println" yöntem başvurusuyla birleştirebileceğiniz varsayılan bir "forEach" yöntemini devralır:

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

2
@Katja Hahn, printlnçıktıya bazı dize eklemek veya eklemek mümkün mü?
gumkins

2
@ sakızlar, EVET, yapabilirsin. Örnek: Arrays.stream (yeni Dize [] {"John", "Sansa", "Cersei"}). Harita (s -> "Merhaba" + s + "!"). ForEach (System.out :: println) ;
Tiago Mussi

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

toString()arasında AbstractCollection bunu temiz ve kolay yeterli olacaktır . AbstractListbir alt sınıftırAbstractCollection , bu yüzden döngü gerekmez ve toArray () gerekmez.

Bu koleksiyonun dize ile temsil edilen halini döndürür. Dize gösterimi, koleksiyon öğelerinin öğelerini, köşeli parantezler ("[]") içine alınmış yineleyici tarafından döndürüldükleri sırayla içerir. Bitişik öğeler "," (virgül ve boşluk) karakterleri ile ayrılır. Öğeler, String.valueOf (Object) tarafından dizelere dönüştürülür.

Listenizde herhangi bir özel nesne kullanıyorsanız, örneğin Öğrenci, toString()anlamlı bir çıktıya sahip olmak için yöntemini geçersiz kılmanız gerekir (bu yöntemi geçersiz kılmak her zaman iyidir)

Aşağıdaki örneğe bakın:

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

çıktı:

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

Çünkü bu cevap tamamen doğru değil. Farkında olmadan polimorfizm kullanıyor. İşte asıl miras hiyerarşisi şöyledir list: List -> Collection -> Iterable -> Object. AbstractCollection öğesinden gerçekten miras alan sınıf ArrayList. Yani bu örnekte ne zaman toString()çağrılır ArrayList, içinde tanımlanan uygulamayı bulur AbstractCollection. İçin miras hiyerarşisine dikkat edin ArrayList:ArrayList -> AbstractList -> AbstractCollection -> Collection -> Iterable -> Object
anon58192932

20

Java 8 Akışları yaklaşımı ...

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

Katja Hahn's ile aynı cevap
Karl Richter

Hayır değil. Maden akışı () kullanır.
Bradley D

@BradleyD Oraya başka bir yöntem çağrısı katmanı ekleyerek hangi kazançlar elde edilir?
Leon

15

Listedeki nesnelerin, toStringekrana anlamlı bir şey basmaları için uygulanması gerekir .

İşte farkları görmek için hızlı bir test:

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

Ve bu yürütüldüğünde, ekrana yazdırılan sonuçlar şunlardır:

t1 = Test$T1@19821f
t2 = 5

T1, toString yöntemini geçersiz kılmadığından, t1 örneği çok kullanışlı olmayan bir şey olarak yazdırılır. Öte yandan, T2String'i geçersiz kılar, bu nedenle G / Ç'de kullanıldığında ne yazdırdığını kontrol ederiz ve ekranda biraz daha iyi bir şey görüriz.


11

Java 8 yapıları List<String> stringListkullanılarak pek çok şekilde yazdırılabilecekleri düşünün :

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)

Bu yaklaşımlar birbirinden nasıl farklı?

İlk Yaklaşım ( Iterable.forEach) - Koleksiyonun yineleyicisi genellikle kullanılır ve bu, hızlı bir şekilde tasarlanmıştır; bu da ConcurrentModificationException, alttaki koleksiyon yineleme sırasında yapısal olarak değiştirilirse atılacağı anlamına gelir . Belirtildiği gibi doc için ArrayList:

Yapısal bir değişiklik, bir veya daha fazla eleman ekleyen veya silen veya destek dizisini açıkça yeniden boyutlandıran herhangi bir işlemdir; sadece bir elemanın değerinin ayarlanması yapısal bir değişiklik değildir.

Bu nedenle ArrayList.forEach, değerin ayarlanmasına herhangi bir sorun olmadan izin verilir. Ve eşzamanlı toplama durumunda, örneğin ConcurrentLinkedQueueyineleyici, zayıf bir şekilde tutarlı olacaktır, bu da, geçirilen eylemlerin forEach, ConcurrentModificationExceptionistisnasız olarak bile yapısal değişiklikler yapmasına izin verildiği anlamına gelir . Ancak burada değişiklikler bu yinelemede görülebilir veya görünmeyebilir.

İkinci Yaklaşım ( Stream.forEach) - Sipariş tanımsız. Sıralı akışlar için olmasa da, şartname bunu garanti etmez. Ayrıca, eylemin doğaya müdahale etmemesi gerekmektedir. Belirtildiği gibi doc :

Bu operasyonun davranışı açıkça belirsizdir. Paralel akışlı boru hatları için, bu işlem akımın karşılaşma sırasına saygı gösterilmesini garanti etmez, çünkü bunu yapmak paralelliğin faydasını feda edecektir.

Üçüncü Yaklaşım ( Stream.forEachOrdered) - Eylem, akışın karşılaşma sırasında gerçekleştirilir. Dolayısıyla, sipariş ne zaman önemli forEachOrderedolursa, ikinci bir düşünce olmadan kullanın . Belirtildiği gibi doc :

Akış tanımlanmış bir karşılaşma sırasına sahipse, akışın karşılaşma sırasında bu akışın her öğesi için bir eylem gerçekleştirir .

Eşzamanlı bir koleksiyon üzerinde yineleme yaparken , ilk yaklaşım koleksiyonun kilidini bir kez alır ve tüm harekete geçirici mesaj yönteminde tutar, ancak akışlarda, önceden oluşturulmuş olmayan kurallara kilitlenmeyen ve güvenmeyen koleksiyonun ayırıcısını kullanırlar -girişim. Akışın iterasyon sırasında modifiye ConcurrentModificationExceptionedilmesi durumunda a atılır veya tutarsız bir sonuç ortaya çıkabilir.

Dördüncü Yaklaşım (Paralel Stream.forEach) - Daha önce de belirtildiği gibi, paralel akışlarda karşılaşılan sıraya uyulması konusunda herhangi bir garanti verilmemektedir. Eylemin, asla böyle olmayacak farklı elemanlar için farklı bir iş parçacığında gerçekleştirilmesi mümkündür forEachOrdered.

Beşinci yaklaşım (paralel Stream.forEachOrdered) -forEachOrdered akışı, ardışık veya paralel olup bağımsız olarak aslında kaynağı tarafından belirtilen sırada elemanlarını işleyecektir. Bu yüzden bunu paralel akışlarla kullanmak mantıklı değil.




7

Benzer sorunlarla karşılaştım. Kodum:

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

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

Yol 1: for döngüsünde bir liste yazdırma

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

Yol 2: Listeyi forEach'ta for döngüsü için yazdırma

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

Yol 3: Listeyi Java 8'de yazdırma

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

5
  1. Listenin ne tür öğeler içerdiğini belirtmediniz, eğer ilkel bir veri türü ise, öğeleri yazdırabilirsiniz.
  2. Ancak öğeler nesne ise, Kshitij Mehta'nın belirttiği gibi, o nesne içinde "toString" yöntemini uygulamanız (geçersiz kılmanız) gerekir - daha önce uygulanmadıysa - ve nesnenin içinden tam anlamıyla bir şey döndürmesine izin vermeniz gerekir, örnek:

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

3

System.out.println(list); benim için çalışıyor.

İşte tam bir örnek:

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

Yazdırılır [Hello, World].


Diğerlerinden farklı değil, önceki cevaplar
Karl Richter

Kopyalayıp yapıştırabileceğiniz ve sonucu gösteren ithalat, sınıf ve ana yöntemlerle tam bir örnek verdim. Bu nedenle, bence oy vermek için bir neden yok
jfmg

3

String dizisinin listesi için

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

2

Bir nesnenin genel üyelerini toString () üzerine geçersiz kılmamışsa, çıktısını alan bir döküm işlevi yazdım. Birisi onu alıcıları aramak için kolayca genişletebilir. Javadoc:

Aşağıdaki kuralları kullanarak belirli bir Object System.out dosyasına döker:

  • Nesne Yinelenebilirse, tüm bileşenleri dökülür.
  • Object veya üst sınıflarından biri toString () öğesini geçersiz kılarsa, "toString" dökümü yapılır
  • Başka bir yöntem Nesnenin tüm kamu üyeleri için özyinelemeli olarak adlandırılır

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

Döngünün bir listenin içeriğini yazdırması için:

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

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

Sonuç:

Element : AA
Element : BB

Tek bir satıra yazdırmak istiyorsanız (sadece bilgi için):

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

Sonuç:

Elements : AA, BB

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

Hangi tipte xve OP'nin sorusuyla nasıl bir ilişkisi var?
Karl Richter

1

Şimdi bunun üzerinde çalışıyorum ...

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

Ne tür nesnelerde saklandığına Listve toString()yöntem için uygulamaya sahip olup olmadığına bağlıdır . System.out.println(list)(tüm standart java nesne türlerini yazdırmalısınız String, Long, Integervs). Özel nesne türleri kullanıyorsanız, özel nesnemizin override toString()yöntemini kullanmamız gerekir .

Misal:

class Employee {
 private String name;
 private long id;

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

Ölçek:

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

öğenin printend olmasını istediğiniz gibi toString () yöntemini geçersiz kılmaya çalışın. böylece yazdırma yöntemi şu olabilir:

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

OP'nin kodu böyle yapar. Çağrı toStringörtük.
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;
     }
   }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.