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



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



Это мой реферальный код...



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


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

557   18  

18 ответов:

вот пример получения распечатки компонента списка:

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

следующее компактно и позволяет избежать цикла в вашем примере кода (и дает вам хорошие запятые):

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

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

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

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

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

если вы используете какой-либо пользовательский объект в своем списке, скажем 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]

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

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

объекты в списке должны быть 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, и мы видим что-то немного лучше на экране.

С помощью функций java 8.

import java.util.Arrays;
import java.util.List;

/**
 * @author AJMAL SHA
 *
 */
public class ForEach {

    public static void main(String[] args) {

        List<String> features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");
        (features).forEach(System.out::println);

    }

}

рассмотрим 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) - Итератор коллекции обычно используется и предназначен для fail-fast что означает, что он будет бросать ConcurrentModificationException если базовая коллекция составляет структурно модифицированных в ходе итерации. Как уже упоминалось в doc на ArrayList:

структурная модификация является любая операция, которая добавляет или удаляет один или больше элементов, или явно изменяет размер резервного массива; просто установка значение элемента не является структурной модификацией.

значит ArrayList.forEach установка значения допускается без каких-либо проблем. И в случае параллельной коллекции, например ConcurrentLinkedQueue итератор будет слабо согласуется что означает действия, переданные в forEach позволены сделать даже структурные изменения без ConcurrentModificationExceptionисключения. Но здесь изменения могут быть или не быть видны в этой итерации.

Второй Подход (Stream.forEach) - Порядок не определен. Хотя это может не произойти для последовательных потоков, но спецификация не гарантирует этого. Также требуется, чтобы действие носило невмешательский характер. Как уже упоминалось в doc:

поведение этой операции явно недетерминированные. Для параллельные трубопроводы потока, эта деятельность не гарантируют к уважайте порядок встречи потока, так как это принесло бы жертву преимущество параллелизма.

Третий Подход (Stream.forEachOrdered) - Действие будет выполняться в порядке встречи потока. Поэтому всякий раз, когда порядок имеет значение использовать forEachOrdered не задумываясь. Как уже упоминалось в doc:

выполнить действие для каждого элемента этого потока, в встреча порядок потока если поток имеет определенный порядок встречи.

при повторении над синхронизировать коллекцию the первый подход возьмет блокировку коллекции один раз и будет удерживать ее во всех вызовах метода действия, но в случае потоков они используют разделитель коллекции, который не блокирует и опирается на уже установленные правила невмешательства. В случае, если коллекция резервного копирования потока изменяется во время итерации a ConcurrentModificationException будет брошен или может возникнуть несогласованный результат.

Четвертый Подход (Параллельный Stream.forEach) - Как уже упоминалось, нет гарантии соблюдения порядка встреч, как ожидалось в случае параллельных потоков. Возможно, что действие выполняется в разных потоках для разных элементов, которые никогда не могут быть случай с forEachOrdered.

Пятый Подход (Параллельный Stream.forEachOrdered) - Элемент forEachOrdered будет обрабатывать элементы в порядке, указанном источнике независимо от того, является ли поток последовательной или параллельной. Поэтому нет смысла использовать это с параллельными потоками.

  1. вы не указали, какие элементы содержит список, если это примитивный тип данных затем вы можете распечатать элементы.
  2. но если элементы являются объектами, то, как упоминал Кшитий Мехта, вам нужно реализовать (переопределить) метод "toString" внутри этого объекта - если он еще не реализован - и пусть он возвращает что-то полное значение из объекта, например:

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

или вы можете просто использовать утилиты Apache Commons:

https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/ArrayUtils.html#toString-java.lang.Object-

List<MyObject> myObjects = ...
System.out.println(ArrayUtils.toString(myObjects));

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

сбрасывает данный объект в систему.выходим, используя следующие правила:

  • если объект является итерационным,все его компоненты сбрасываются.
  • если объект или один из его суперклассов переопределяет 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();
}

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].

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

для списка массива String

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

попробуйте переопределить метод toString (), поскольку вы хотите, чтобы элемент был printend. такой метод печати может быть такой:

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

Я работаю над этим сейчас...

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

Comments

    Ничего не найдено.