Java에서 List의 모든 요소를 ​​인쇄하는 방법은 무엇입니까?


236

의 모든 요소를 ​​인쇄하려고 List하지만 Object값 이 아닌 포인터를 인쇄하고 있습니다.

이것은 내 인쇄 코드입니다 ...

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

아무도 요소의 가치를 인쇄하지 않는 이유를 알려주세요.


3
어떤 유형으로 선언 했 List습니까? 어떻게 선언하고 인스턴스화했는지 보여주세요.
Makoto

toString을 호출하면 클래스에 대한 설명을 얻거나 목록에 포함 된 유형에 대한 toString 메소드를 대체합니다.
L7ColWinters

그것이 인쇄하도록 지시하는 것입니다. 다른 toString 또는 다른 읽을 수있는 문자열이 필요합니다.
Dave Newton

ArrayList <class> list = 새로운 ArrayList <class> ();
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수업 소개 는 질문과 어떤 관련이 있습니까?
Karl Richter

4
목록 내에서 어떤 종류의 객체를 알지 못하기 때문에 가정에 불과합니다.
Crazenezz

477

다음은 컴팩트하고 예제 코드에서 루프를 피하고 멋진 쉼표를 제공합니다.

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

그러나 다른 사람들이 지적했듯이 목록 내부의 객체에 대해 현명한 toString () 메소드가 구현되어 있지 않으면 관찰중인 객체 포인터 (사실 해시 코드)를 얻게됩니다. 목록에 있든 없든 상관 없습니다.


18
무엇에 대해 단지 list.toString().
Jaskey

22
'list.toString ()'을 사용하면 정상적인 동작을 재정의하는 List 인터페이스의 사용자 정의 구현이 아닌 한 개별 요소를 인쇄하지 않습니다 (클래스 이름 및 해시 코드를 다소 인쇄).
Holly Cummins

1
사용자 정의 클래스를 사용하고 재정의하지 않으면 toString솔루션에서 클래스 이름과 해시 코드도 인쇄합니다.
Jaskey

[value1, value2, value3]으로 인쇄합니다. []없이 인쇄 할 수 있습니까?
데드 엔드

실제로 @Jaskey가 옳습니다. 그들의 대답이 더 좋습니다. 이 Arrays메소드는 배열에 유용하지만 이제의 서브 클래스에는 필요하지 않습니다 AbstractCollection.
Holly Cummins

100

Java 8부터 List는 다음과 같이 메소드 참조 "System.out :: println"과 결합 할 수있는 기본 "forEach"메소드를 상속합니다.

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

2
@Katja Hahn, println출력에 문자열을 추가하거나 추가 할 수 있습니까?
gumkins

2
@ gumkins, 예, 가능합니다. 예 : Arrays.stream (new String [] { "John", "Sansa", "Cersei"}). map (s-> "Hi"+ s + "!"). forEach (System.out :: println) ;
Tiago Mussi

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

자바 8 스트림 접근

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

Katja Hahn와 같은 답변
Karl Richter

아닙니다. 광산은 stream ()을 활용합니다.
Bradley 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을 재정의하므로 I / O에서 사용될 때 인쇄되는 내용을 제어하고 화면에서 조금 더 나은 것을 볼 수 있습니다.


11

Java 8 구문을 List<String> stringList사용하여 여러 가지 방법으로 인쇄 할 수있는 것을 고려하십시오 .

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)- 순서가 정의되지 않았습니다. 순차적 인 스트림에서는 발생하지 않을 수 있지만 사양에서는이를 보증하지 않습니다. 또한 그 행동은 본질적으로 방해가되지 않아야한다. doc 에서 언급했듯이 :

이 작업의 동작은 명시 적으로 비 결정적입니다. 병렬 스트림 파이프 라인의 경우이 작업은 스트림의 발생 순서를 존중한다고 보장하지는 않습니다. 병렬 처리의 이점을 희생 할 수 있습니다.

세 번째 접근 ( Stream.forEachOrdered)- 스트림의 발생 순서에 따라 작업이 수행됩니다. 따라서 주문이 중요 할 때마다 다시 forEachOrdered생각하지 않아도됩니다. 문서 에서 언급했듯이 :

스트림에 정의 된 발생 순서가있는 경우 스트림발생 순서 로이 스트림의 각 요소에 대해 작업을 수행합니다 .

이상 반복하는 동안 동기화 수집 첫 번째 방법은 모든 걸쳐 그들이 잠금 및 비의 이미 확립 된 규칙에 의존하지 않는 콜렉션의 spliterator를 사용하는 액션 메소드에 있지만, 스트림의 경우에는 통화를 개최 할하면 컬렉션의 잠금을 취할 것 -간섭. 반복하는 동안 스트림을 수집하는 콜렉션이 수정되는 경우 a 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 루프에서 목록 인쇄

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

방법 3 : Java 8에서 목록 인쇄

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

5
  1. 목록에 어떤 종류의 요소가 포함되어 있는지 지정하지 않았습니다. 기본 데이터 유형 인 경우 요소를 인쇄 할 수 있습니다.
  2. 그러나 요소가 객체 인 경우 Kshitij Mehta가 언급했듯이 해당 객체 내에서 "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]됩니다.


다른 이전 답변과 다르지 않음
Karl Richter

가져 오기, 클래스 및 주요 방법으로 전체 예제를 제공하여 복사하여 붙여 넣을 수 있으며 결과를 보여주었습니다. 그러므로 제 의견으로는 투표 할 이유가 없습니다
jfmg


2

toString ()을 재정의하지 않은 경우 기본적으로 객체의 공개 멤버를 출력하는 덤프 함수를 작성했습니다. getter를 호출하기 위해 쉽게 확장 할 수 있습니다. 자바 독 :

다음 규칙을 사용하여 지정된 Object를 System.out에 덤프합니다.

  • Object가 Iterable이면 모든 구성 요소가 덤프됩니다.
  • Object 또는 그 슈퍼 클래스 중 하나가 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.stream().map(x -> x.getName()).forEach(System.out::println);

어떤 유형이 x있으며 OP 질문과 어떻게 관련이 있습니까?
Karl Richter

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

에 저장된 객체 유형 ListtoString()메소드 구현 여부 에 따라 다릅니다 . System.out.println(list)(모든 표준 자바 객체 유형을 인쇄해야합니다 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

요소가 printend되도록 원하는 toString () 메소드를 대체하십시오. 인쇄 방법은 다음과 같습니다.

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

그것이 OP의 코드가하는 일입니다. 호출 toString은 암시 적입니다.
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;
     }
   }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.