Як роздрукувати всі елементи списку на Java?


236

Я намагаюся роздрукувати всі елементи а List, проте це друк покажчика, Objectа не значення.

Це мій код друку ...

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

Чи може хтось допомогти мені, чому він не друкує значення елементів.


3
Якого типу ти оголосив List? Покажіть нам, як ви це заявили та підтвердили.
— Макото

вам потрібно зателефонувати до toString, і ви отримаєте пояснення щодо класу або замініть метод toString для типу, який міститься у списку
— L7ColWinters

Це те, що ви говорите йому для друку - вам потрібна інша тота String або інший читабельний рядок.
— Дейв Ньютон

ArrayList <class> list = новий ArrayList <class> ();
— користувач1335361

4
Зверніть увагу , що є більш компактний синтаксис можна використовувати для виконання тих же речей: for (Object obj : list) {System.out.println(obj);}.
— aroth

Відповіді:


114

Ось приклад отримання роздруківки компонента списку:

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
Як вступ до Modelкласу пов'язаний із питанням?
— Карл Ріхтер

4
Це лише припущення, оскільки я не знаю, що таке об’єкт у списку.
— Crazenezz

477

Далі є компактним і дозволяє уникнути циклу у вашому прикладі коду (і дає приємні коми):

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

Однак, як зазначали інші, якщо у вас немає розумних методів toString (), реалізованих для об'єктів всередині списку, ви отримаєте об'єктні покажчики (насправді хеш-коди), які ви спостерігаєте. Це вірно, чи є вони у списку чи ні.


18
А що тільки list.toString().
— Жаскі

22
Просто використання "list.toString ()" не буде друкувати окремі елементи, якщо тільки це не власна реалізація інтерфейсу "Список", що переосмислює нормальну поведінку (для друку назви класу та хеш-коду, більш-менш).
— Холлі Каммінз

1
Якщо вони використовують користувальницький клас і не переосмислюють toString, ваше рішення також надрукує його ім'я класу та хеш-код.
— Jaskey

Він друкується як [value1, value2, value3]. Чи можемо ми друкувати як без []?
— декад

Насправді @Jaskey має рацію - їх відповідь краща. ArraysМетод корисний для масивів, але тепер не потрібно для підкласів AbstractCollection.
— Холлі Каммінс

100

Оскільки Java 8, List успадковує за замовчуванням метод "forEach", який ви можете комбінувати з посиланням на метод "System.out :: println", як це:

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

2
@Katja Hahn, чи можна додати чи додати якийсь рядок до printlnвиводу?
— gumkins

2
@gumkins, ТАК, ти можеш. Приклад: Arrays.stream (новий String [] {"John", "Sansa", "Cersei"}). Map (s -> "Привіт" + s + "!"). ForEach (System.out :: println) ;
— Тіаго Мусі

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

toString()з AbstractCollection буде чистою і досить легко , щоб зробити це . AbstractListє підкласом AbstractCollection, тому немає необхідності в циклі і не потрібен toArray ().

Повертає рядкове подання цієї колекції. Представлення рядків складається із списку елементів колекції у порядку їх повернення ітератором, укладеним у квадратні дужки ("[]"). Суміжні елементи розділені символами "," (кома та пробіл). Елементи перетворюються на рядки, як String.valueOf (Object).

Якщо ви використовуєте будь-який нестандартний об'єкт у своєму списку, скажімо, Student, вам потрібно переосмислити його toString()метод (завжди добре замінити цей метод), щоб мати значущий результат

Дивіться приклад нижче:

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

вихід:

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

Тому що ця відповідь не зовсім правильна. Це використання поліморфізму, не усвідомлюючи цього. Ось фактична ієрархія наслідування list: List -> Collection -> Iterable -> Object. Клас, який насправді успадковує від AbstractCollection ArrayList. Отже, у цьому прикладі, коли toString()він називається, він знаходить ArrayListреалізацію, яка визначена в AbstractCollection. Зверніть увагу на ієрархію спадкування для ArrayList:ArrayList -> AbstractList -> AbstractCollection -> Collection -> Iterable -> Object
— anon58192932

20

Підхід потоків Java 8 ...

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

така ж відповідь, як у Каті Хан
— Карл Ріхтер

Ні, це не так. Потік шахтного плеча ().
— Бредлі D

@BradleyD які надбавки реалізуються додавши туди ще один шар викликів методу?
— Леон

15

Об'єкти зі списку повинні бути toStringреалізовані для того, щоб надрукувати на екрані щось значиме.

Ось короткий тест, щоб побачити відмінності:

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

І коли це виконується, результати, що друкуються на екрані:

t1 = Test$T1@19821f
t2 = 5

Оскільки T1 не замінює метод toString, його екземпляр t1 друкується як щось, що не дуже корисно. З іншого боку, T2 перекриває ToString, тому ми контролюємо, що він друкує, коли він використовується у вході / виводі, і ми бачимо щось трохи краще на екрані.


11

Розглянемо, List<String> stringListяку можна надрукувати багатьма способами за допомогою конструкцій 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)

Чим ці підходи відрізняються один від одного?

Перший підхід ( Iterable.forEach) - Ітератор колекції, як правило, використовується, і він розроблений таким чином, що не виходить з ладу, а це означає, що він викине, ConcurrentModificationExceptionякщо базова колекція буде структурно модифікована під час ітерації. Як зазначено в документі для ArrayList:

Структурна модифікація - це будь-яка операція, яка додає або видаляє один або кілька елементів або явно змінює розмір резервного масиву; просто встановлення значення елемента не є структурною модифікацією.

Таким чином, це означає, що ArrayList.forEachвстановлення значення дозволено без жодних питань. А у випадку одночасного збору, наприклад, ConcurrentLinkedQueueітератор буде слабко узгодженим, що означає дії, що передаютьсяforEach виконані дії дозволяють вносити навіть структурні зміни без ConcurrentModificationExceptionвинятку. Але тут модифікації можуть бути або не помітні в цій ітерації.

Другий підхід ( Stream.forEach) - Порядок не визначений. Хоча це може не траплятися для послідовних потоків, але специфікація цього не гарантує. Також дії повинні мати не заважаючий характер. Як згадується в документі :

Поведінка цієї операції явно недетерміновано. Для паралельних потокових трубопроводів ця операція не гарантує дотримання порядку зустрічі потоку, оскільки це може принести шкоду паралелізму.

Третій підхід ( Stream.forEachOrdered) - Дія буде виконуватися в порядку зустрічі потоку. Тож, коли питання про замовлення використовуйте, forEachOrderedне замислюючись. Як зазначено в документі :

Виконує дію для кожного елемента цього потоку в порядку зустрічі потоку, якщо потік має визначений порядок зустрічі.

У той час як ітерація по синхронному колекції з першим підходом б заблокувати колекцію раз і проведуть його через всі виклики до методу дії, але в разі потоків , які вони використовують spliterator колекції, яка не блокує і спирається на вже встановлені правила неурядового -втручання. У випадку, якщо резервна копія потоку колекції буде змінена під час ітерації, це ConcurrentModificationExceptionможе бути кинуто або може виникнути непослідовий результат.

Четвертий підхід (паралельний Stream.forEach) - Як вже було сказано, жодна гарантія дотримання порядку зустрічей, як очікувалося, у разі паралельних потоків. Можливо, що дії виконуються в різних нитках для різних елементів, що ніколи не може бути з цим forEachOrdered.

П'ятий підхід (паралельний Stream.forEachOrdered) -forEachOrdered буде обробляти елементи в порядку , зазначеному джерелі , незалежно від того , чи є послідовний або паралельний потік. Тому немає сенсу використовувати це при паралельних потоках.




7

Я зіткнувся з подібними проблемами. Мій код:

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

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

Спосіб 1: друк списку в циклі for

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

Спосіб 2: друк списку в forEach, для циклу

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

Спосіб 3: друк списку в java 8

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

5
  1. Ви не вказали, які елементи містить список, якщо це примітивний тип даних то ви можете роздрукувати елементи.
  2. Але якщо елементи є об'єктами, тоді, як згадував Кшитій Мехта, вам потрібно реалізувати (замінити) метод "toString" всередині цього об'єкта - якщо він ще не реалізований - і нехай він поверне щось об'єктне значення зсередини об'єкта, наприклад:

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

3

System.out.println(list); працює для мене.

Ось повний приклад:

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

Він надрукує [Hello, World].


Не відрізняється від інших, більш ранніх відповідей
— Карл Ріхтер

Я наводив повний приклад з імпортом, класом та основним методом, який ви можете скопіювати та вставити, і показав результат. Тому, на мою думку, немає підстав проголосувати це
— jfmg


2

Я написав дамп-функцію, яка в основному виводить публічні члени об'єкта, якщо він не перекрив toString (). Можна було легко розширити його на дзвінки. Javadoc:

Скидає заданий об’єкт на System.out, використовуючи такі правила:

  • Якщо Об'єкт є Ітерабельним, всі його компоненти скидаються.
  • Якщо Об'єкт або один із його суперклассів перекриває ToString (), "toString" скидається
  • В іншому випадку метод називається рекурсивно для всіх громадських членів Об'єкта

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

Для циклу друку вмісту списку:

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

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

Результат:

Element : AA
Element : BB

Якщо ви хочете надрукувати в один рядок (лише для інформації):

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

Результат:

Elements : AA, BB


1

Я, мабуть, працюю над цим зараз ...

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

Це залежить від того, який тип об'єктів зберігається в Listі чи є у нього реалізація для toString()методу. System.out.println(list)повинен друкувати всі стандартні типи об'єктів Java ( String, Long, і Integerт.д.). У випадку, якщо ми використовуємо власні типи об’єктів, то нам це потрібноoverride toString() метод нашого власного об'єкта.

Приклад:

class Employee {
 private String name;
 private long id;

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

Тест:

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

спробуйте замінити метод toString () так, як ви хочете, щоб елемент був принтеном. тож спосіб друку може бути таким:

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

Ось що робить код ОП. Заклик до toString- неявний.
— Карл Ріхтер

-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;
     }
   }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.