Как распечатать все элементы списка на Java?
Я пытаюсь распечатать все элементы List, однако он печатает указатель Object а не значение.
Это мой реферальный код...
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
может ли кто-нибудь помочь мне, почему он не печатает значение элементов.
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]
объекты в списке должны быть
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будет обрабатывать элементы в порядке, указанном источнике независимо от того, является ли поток последовательной или параллельной. Поэтому нет смысла использовать это с параллельными потоками.
- вы не указали, какие элементы содержит список, если это примитивный тип данных затем вы можете распечатать элементы.
но если элементы являются объектами, то, как упоминал Кшитий Мехта, вам нужно реализовать (переопределить) метод "toString" внутри этого объекта - если он еще не реализован - и пусть он возвращает что-то полное значение из объекта, например:
class Person { private String firstName; private String lastName; @Override public String toString() { return this.firstName + " " + this.lastName; } }
или вы можете просто использовать утилиты Apache Commons:
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].
попробуйте переопределить метод 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