Java 컬렉션을 훌륭하게 인쇄 (toString이 출력을 제대로 반환하지 않음)


211

나는 인쇄 할 Stack<Integer>로 잘 이클립스 디버거가하는 (즉, 같은 개체 [1,2,3...])하지만, 그것을 인쇄하기 out = "output:" + stack이 좋은 결과를 반환하지 않습니다.

명확히하기 위해 Java의 내장 컬렉션에 대해 이야기하고 있으므로이를 재정의 할 수 없습니다 toString().

인쇄 가능한 멋진 버전의 스택을 얻으려면 어떻게해야합니까?


7
적어도 Java 7에서 AbstractCollection@toString(그리고 따라서 String + Stack)는 이미 원하는대로 인쇄합니다.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

답변:


317

배열로 변환 한 다음 다음을 사용하여 인쇄 할 수 있습니다 Arrays.toString(Object[]).

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

11
나는 그것을 좋아한다. 간단하고 깨끗합니다. 정직한 Collections에는 toString 메소드도 필요하지만 작동합니다.
Tovi7

1
@ Tovi7 대부분의 OOTB 컬렉션은 이미 읽을 수있는 toString ()을 제공하지만 배열은 그렇지 않기 때문에 아마도 그렇지 않습니다.
맥스 Nanasy

@Boosha 스택을 문자열로 변환하는 데 O (n) 시간이 걸리고 콘솔에 문자열을 인쇄하는 데 O (n) 시간이 걸립니다
Zach Langley

stack.toArray()매우 비싸고 CPU, 시간 및 메모리가 현명 할 수 있습니다. 원본 컬렉션 / 반복 가능 항목을 반복하는 솔루션은 리소스 소비가 적을 것입니다.
AlikElzin-kilaka

52
String.join(",", yourIterable);

(자바 8)


12
yourIterable은 Iterable이어야합니까? CharSequence를 확장 함>
Nathan

3
String.join ( ",", yourCollection.stream (). map (o-> o.toString ()). collect (Collectors.toList ()))
user1016765

@ user1016765 yourCollection.stream().map( o -> o.toString() ).collect( joining(",") ))는 왼쪽에서 오른쪽으로 읽는 것이 좋습니다. 중간 목록으로 수행 된 작업을 두뇌에서 계산하기 위해 앞을 다시 볼 필요가 없습니다
cdalxndr

18

Java 8 스트림 및 콜렉터를 사용하면 쉽게 수행 할 수 있습니다.

String format(Collection<?> c) {
  String s = c.stream().map(Object::toString).collect(Collectors.joining(","));
  return String.format("[%s]", s);
}

먼저 mapwith Object::toStringCollection<String>사용하여 결합 컬렉터를 사용하여 콜렉션의 모든 항목 ,을 분리 문자 로 결합합니다 .


22
나는 대답에서 '쉽게'라는 단어를 제거하지 말아야했다 Collections.toString(stack). ;-) 쉽다.
FrVaBe

String.format ()을 호출하는 이유는 무엇입니까? 대괄호를 얻는 것입니까?
Jolta

18

Apache Commons 프로젝트에서 제공하는 MapUtils 클래스는 MapUtils.debugPrint맵을 인쇄 하는 방법을 제공합니다 .


내가 아는 한에서는 아니다. 나는 구아바 도서관에 굉장히 익숙하지는 않지만, 그것이 있다면 놀라지 않을 것입니다.
tlavarea

AbstractMap # toString 이 이미 수행 하므로 Java 6 이상에서는 필요 하지 않습니다. 지도 만 질문 : stackoverflow.com/questions/2828252/map-to-string-in-java
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

12

System.out.println (Collection c)은 이미 모든 유형의 컬렉션을 읽을 수있는 형식으로 인쇄합니다. collection에 사용자 정의 오브젝트가 포함 된 경우에만 컨텐츠를 표시하려면 사용자 정의 클래스에서 toString ()을 구현해야합니다.


12

클래스에서 toString ()을 구현하십시오.

이것을 쉽게하기 위해 Apache Commons ToStringBuilder 를 권장합니다 . 그것으로, 당신은 이런 종류의 방법을 작성해야합니다 :

public String toString() {
     return new ToStringBuilder(this).
       append("name", name).
       append("age", age).
       toString(); 
}

이런 종류의 출력을 얻으려면 :

Person @ 7f54 [이름 = Stephen, 나이 = 29]

또한 반사 구현이 있습니다.


ToStringBuilder는 일반적으로 복잡한 데이터 구조의 경우 정보를 전달하는 Bean 및 오브젝트에 더 적합합니다. 스택 객체가 저장된 모든 항목을 인쇄하지 않으면 도움이되지 않습니다.
Uri

2
리플렉션 사용 ToStringBuilder, HashCodeBuilder 및 EqualsBuilder는 매우 효과가 없습니다. 출력은 괜찮지 만이 클래스는 거의주의 성과가 거의 없습니다 ...
Jan Hruby

2
이 질문은 클래스가 내장 컬렉션이므로 명시 적으로 toString ()을 수정할 수 없습니다.
Rasmus Kaj


9

본인 toString()의 클래스를 재정의 하고 가능한 한 프로세스를 자동화하는 것에 대한 위의 의견에 동의합니다 .

당신이 클래스에 들어 하지 않았다 정의, 당신은 쓸 수 있습니다 ToStringHelper자신의 취향에 처리 한하려는 각 라이브러리 클래스에 대한 오버로드 된 메서드와 클래스를 :

public class ToStringHelper {
    //... instance configuration here (e.g. punctuation, etc.)
    public toString(List m) {
        // presentation of List content to your liking
    }
    public toString(Map m) {
        // presentation of Map content to your liking
    }
    public toString(Set m) {
        // presentation of Set content to your liking
    }
    //... etc.
}

편집 : xukxpvfzflbbld의 의견에 응답하여 앞에서 언급 한 사례에 대한 가능한 구현이 있습니다.

package com.so.demos;

import java.util.List;
import java.util.Map;
import java.util.Set;

public class ToStringHelper {

    private String separator;
    private String arrow;

    public ToStringHelper(String separator, String arrow) {
        this.separator = separator;
        this.arrow = arrow;
    }

   public String toString(List<?> l) {
        StringBuilder sb = new StringBuilder("(");
        String sep = "";
        for (Object object : l) {
            sb.append(sep).append(object.toString());
            sep = separator;
        }
        return sb.append(")").toString();
    }

    public String toString(Map<?,?> m) {
        StringBuilder sb = new StringBuilder("[");
        String sep = "";
        for (Object object : m.keySet()) {
            sb.append(sep)
              .append(object.toString())
              .append(arrow)
              .append(m.get(object).toString());
            sep = separator;
        }
        return sb.append("]").toString();
    }

    public String toString(Set<?> s) {
        StringBuilder sb = new StringBuilder("{");
        String sep = "";
        for (Object object : s) {
            sb.append(sep).append(object.toString());
            sep = separator;
        }
        return sb.append("}").toString();
    }

}

이것은 본격적인 구현이 아니라 시작에 불과합니다.


7

JAVA"Objects"클래스를 사용할 수 있습니다 (1.7 이후 사용 가능).

Collection<String> myCollection = Arrays.asList("1273","123","876","897");
Objects.toString(myCollection);

출력 : 1273, 123, 876, 897

또 다른 가능성은 Google Guave"MoreObjects"클래스 를 사용하는 것입니다.이 클래스 는 유용한 도우미 기능을 많이 제공합니다.

MoreObjects.toStringHelper(this).add("NameOfYourObject", myCollection).toString());

출력 : NameOfYourObject = [1273, 123, 876, 897]

구아바 문서


1
Objects.toString()toString()컬렉션을 호출하기 만하면 됩니다. 귀하의 예에서, 이것은 아마도 toString()배열 지원 컬렉션에서 아마도 꽤 잘 인쇄 되기 때문에 작동합니다 .
GuyPaddock

3

함께 아파치 코 몬즈 3 , 당신은 전화를 걸

StringUtils.join(myCollection, ",")

3

Java8에서

//will prints each element line by line
stack.forEach(System.out::println);

또는

//to print with commas
stack.forEach(
    (ele) -> {
        System.out.print(ele + ",");
    }
);

1

사용자 정의 객체가 포함 된 짝수 컬렉션을 인쇄하도록 이전 예제를 수정했습니다.

public class ToStringHelper {

    private  static String separator = "\n";

    public ToStringHelper(String seperator) {
        super();
        ToStringHelper.separator = seperator;

    }

    public  static String toString(List<?> l) {
        StringBuilder sb = new StringBuilder();
        String sep = "";
        for (Object object : l) {
            String v = ToStringBuilder.reflectionToString(object);
            int start = v.indexOf("[");
            int end = v.indexOf("]");
            String st =  v.substring(start,end+1);
            sb.append(sep).append(st);
            sep = separator;
        }
        return sb.toString();
    }

    public static String toString(Map<?,?> m) {
        StringBuilder sb = new StringBuilder();
        String sep = "";
        for (Object object : m.keySet()) {
            String v = ToStringBuilder.reflectionToString(m.get(object));
            int start = v.indexOf("[");
            int end = v.indexOf("]");
            String st =  v.substring(start,end+1);
            sb.append(sep).append(st);
            sep = separator;
        }
        return sb.toString();
    }

    public static String toString(Set<?> s) {
        StringBuilder sb = new StringBuilder();
        String sep = "";
        for (Object object : s) {
            String v = ToStringBuilder.reflectionToString(object);
            int start = v.indexOf("[");
            int end = v.indexOf("]");
            String st =  v.substring(start,end+1);
            sb.append(sep).append(st);
            sep = separator;
        }
        return sb.toString();
    }

    public static void print(List<?> l) {
        System.out.println(toString(l));    
    }
    public static void print(Map<?,?> m) {
        System.out.println(toString(m));    
    }
    public static void print(Set<?> s) {
        System.out.println(toString(s));    
    }

}

1

toString()요즘 대부분의 컬렉션은 Java 에서 유용합니다 (Java7 / 8). 따라서 필요한 것을 연결하기 위해 스트림 작업을 수행 할 필요가 없으며 toString컬렉션의 값 클래스를 재정의 하면 필요한 것을 얻을 수 있습니다.

모두 AbstractMapAbstractCollection의이 요소마다 toString을 호출하여 toString ()를 구현합니다.

아래는 행동을 보여주는 테스트 클래스입니다.

import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;

public class ToString {
  static class Foo {
    int i;
    public Foo(int i) { this.i=i; }
    @Override
    public String toString() {
        return "{ i: " + i + " }";
    }
  }
  public static void main(String[] args) {
    List<Foo> foo = new ArrayList<>();
    foo.add(new Foo(10));
    foo.add(new Foo(12));
    foo.add(new Foo(13));
    foo.add(new Foo(14));
    System.out.println(foo.toString());
    // prints: [{ i: 10 }, { i: 12 }, { i: 13 }, { i: 14 }]

    Map<Integer, Foo> foo2 = new HashMap<>();
    foo2.put(10, new Foo(10));
    foo2.put(12, new Foo(12));
    foo2.put(13, new Foo(13));
    foo2.put(14, new Foo(14));
    System.out.println(foo2.toString());
    // prints: {10={ i: 10 }, 12={ i: 12 }, 13={ i: 13 }, 14={ i: 14 }}
  }
}

1

JSON

대안 솔루션은 컬렉션을 JSON 형식 으로 변환 하고 Json-String을 인쇄하는 것일 수 있습니다 . 장점은를 구현할 필요없이 형식이 잘되어 있고 읽을 수있는 Object-String toString()입니다.

Google의 Gson을 사용한 예 :

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

...

    printJsonString(stack);

...
public static void printJsonString(Object o) {
    GsonBuilder gsonBuilder = new GsonBuilder();
    /*
     * Some options for GsonBuilder like setting dateformat or pretty printing
     */
    Gson gson = gsonBuilder.create();
    String json= gson.toJson(o);
    System.out.println(json);
}

0

이것이 내장 클래스가 아닌 고유 한 컬렉션 클래스 인 경우 toString 메서드를 재정의해야합니다. Eclipse는 유선 형식이없는 오브젝트에 대해 해당 함수를 호출합니다.


그리고 이클립스는 어떻게 유선 형식의 클래스를 어떻게 형식화합니까? 그것이 내가 찾고있는 것입니다.
Elazar Leibovich

0

Sop on Collection을 호출 할 때 ConcurrentModification예외가 발생할 수 있으므로주의하십시오 . toString각 Collection의 내부 메소드는 내부적으로 Collection을 호출 Iterator하기 때문입니다.


0

를 제외한 모든 컬렉션에서 작동 Map하지만 지원하기도 쉽습니다. 필요한 경우이 3 개의 문자를 인수로 전달하도록 코드를 수정하십시오.

static <T> String seqToString(Iterable<T> items) {
    StringBuilder sb = new StringBuilder();
    sb.append('[');
    boolean needSeparator = false;
    for (T x : items) {
        if (needSeparator)
            sb.append(' ');
        sb.append(x.toString());
        needSeparator = true;
    }
    sb.append(']');
    return sb.toString();
}

0

당신은 사용해 볼 수 있습니다

org.apache.commons.lang3.builder.ToStringBuilder.reflectionToString(yourCollection);

0

작업을 단순화 할 수있는 두 가지 방법이 있습니다. 1. Gson 라이브러리를 가져옵니다. 2. 롬복을 사용하십시오.

둘 다 객체 인스턴스에서 문자열을 만드는 데 도움이됩니다. Gson은 객체를 구문 분석하고 lombok은 클래스 객체 toString 메소드를 재정의합니다.

Gson prettyPrint에 대한 예를 들어 객체와 객체 컬렉션을 인쇄하는 도우미 클래스를 만듭니다. lombok을 사용하는 경우 클래스를 @ToString으로 표시하고 객체를 직접 인쇄 할 수 있습니다.

@Scope(value = "prototype")
@Component
public class DebugPrint<T> {
   public String PrettyPrint(T obj){
      Gson gson = new GsonBuilder().setPrettyPrinting().create();
      return gson.toJson(obj);
   }
   public String PrettyPrint(Collection<T> list){
      Gson gson = new GsonBuilder().setPrettyPrinting().create();
      return list.stream().map(gson::toJson).collect(Collectors.joining(","));
   }

}

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.