Как распечатать все элементы списка в Java?


236

Я пытаюсь распечатать все элементы List, но он печатает указатель, Objectа не значение.

Это мой печатный код ...

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

Может ли кто-нибудь, пожалуйста, помогите мне, почему он не печатает значение элементов.


3
Какой тип вы объявили Listбыть? Покажите нам, как вы объявили и создали его экземпляр.
Макото

Вы должны вызвать toString, и вы получите объяснение класса или переопределить метод toString для типа, который содержится в списке
L7ColWinters

Это то, что вы говорите, чтобы напечатать - вам нужна другая строка toString или другая читаемая строка.
Дейв Ньютон,

ArrayList <класс> список = новый ArrayList <класс> ();
user1335361

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().
Jaskey

22
Простое использование list.toString () не приведет к печати отдельных элементов, если только это не пользовательская реализация интерфейса List, которая переопределяет нормальное поведение (для печати имени класса и хэш-кода, более или менее).
Холли Камминс

1
Если они используют пользовательский класс и не переопределяют toString, ваше решение также напечатает его имя класса и хэш-код.
Jaskey

Он печатается как [значение1, значение2, значение3]. Можем ли мы печатать как без []?
Тупик

На самом деле, @Jaskey прав - их ответ лучше. Этот Arraysметод полезен для массивов, но не нужен для подклассов AbstractCollection.
Холли Камминс

100

Начиная с Java 8, List наследует метод «forEach» по умолчанию, который можно объединить со ссылкой на метод «System.out :: println» следующим образом:

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

2
@ Катя Хан, можно ли добавить или добавить строку для printlnвывода?
Gumkins

2
@ gumkins, ДА, ты можешь. Пример: Arrays.stream (new String [] {"John", "Sansa", "Cersei"}). Map (s -> "Hi" + s + "!"). ForEach (System.out :: println) ;
Тиаго Мусси

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

toString()из AbstractCollection будет чистой и достаточно легко , чтобы сделать это . AbstractListявляется подклассом AbstractCollection, так что нет необходимости для цикла for и не нужно toArray ().

Возвращает строковое представление этой коллекции. Строковое представление состоит из списка элементов коллекции в том порядке, в котором они возвращаются ее итератором, заключенных в квадратные скобки ("[]"). Смежные элементы разделяются символами «,» (запятая и пробел). Элементы преобразуются в строки как String.valueOf (Object).

Если вы используете какой-либо пользовательский объект в своем списке, скажем «Студент», вам нужно переопределить его 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


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, поэтому мы контролируем, что он печатает, когда он используется в I / O, и мы видим что-то немного лучше на экране.


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 коллекции, которая не блокирует и опирается на уже установленные правилах неправительственного -interference. В случае, если поддержка итерации потока изменяется во время итерации, 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

Цикл For для печати содержимого списка:

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 (), так как вы хотите, чтобы элемент был printend. поэтому метод печати может быть таким:

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.