IT story

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

hot-time 2020. 5. 8. 08:23
반응형

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


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

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

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


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

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

String.join(",", yourIterable);

(자바 8)


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


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>사용하여 결합 컬렉터를 사용하여 콜렉션의 모든 항목 ,을 분리 문자 로 결합합니다 .


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

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

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

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

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

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


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


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

}

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


구아바는 좋은 옵션처럼 보입니다.

Iterables.toString(myIterable)


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

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

출력 : 1273, 123, 876, 897

Another possibility is to use the "MoreObjects" class from Google Guave, which provides many of useful helper functions:

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

Output: NameOfYourObject=[1273, 123, 876, 897]

Guava docs


With Apache Commons 3, you want to call

StringUtils.join(myCollection, ",")

In Java8

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

or

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

Just Modified the previous example to print even collection containing user defined objects.

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

}

most collections have a useful toString() in java these days (Java7/8). So there is no need to do stream operations to concatenate what you need, just override toString of your value class in the collection and you get what you need.

both AbstractMap and AbstractCollection implement toString() by calling toString per element.

below is a testclass to show behaviour.

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

If this is your own collection class rather than a built in one, you need to override its toString method. Eclipse calls that function for any objects for which it does not have a hard-wired formatting.


Be careful when calling Sop on Collection, it can throw ConcurrentModification Exception. Because internally toString method of each Collection internally calls Iterator over the Collection.


Should work for any collection except Map, but it's easy to support, too. Modify code to pass these 3 chars as arguments if needed.

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

You can try using

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

참고URL : https://stackoverflow.com/questions/395401/printing-java-collections-nicely-tostring-doesnt-return-pretty-output

반응형

'IT story' 카테고리의 다른 글

SQLAlchemy IN 절  (0) 2020.05.08
MVC 4 @Scripts“존재하지 않습니다”  (0) 2020.05.08
SQL 대소 문자 구분 문자열 비교  (0) 2020.05.08
Cocoa 앱에서 터미널 명령 실행  (0) 2020.05.08
자바 연관 배열  (0) 2020.05.08