Javaコレクションを適切に印刷する(toStringはきれいな出力を返さない)


211

Stack<Integer>オブジェクトをEclipseデバッガー(つまり[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
私はそれが好きです。シンプルでクリーン。正直に言うと、コレクションにはtoStringメソッドも必要ですが、これも機能します。
Tovi7

1
@ Tovi7ほとんどのOOTBコレクションは既に読み取り可能なtoString()を提供しているのに対し、配列は提供していないため、おそらくそうではありません。
Max Nanasy 2013年

@Booshaスタックを文字列に変換するにはO(n)時間もかかり、文字列をコンソールに出力するにはO(n)時間もかかる
Zach Langley

stack.toArray()CPU、時間、メモリの点で非常に高価になる可能性があります。元のコレクション/反復可能オブジェクトを反復処理するソリューションは、おそらくリソースの消費が少ないでしょう。
AlikElzin-kilaka

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

(Java 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::toStringて作成Collection<String>し、joining collector を使用して、コレクション内のすべての項目,を区切り文字として結合します。


22
私は答えから「簡単に」という言葉を取り除かないように控えなければなりませんでした;-) Collections.toString(stack)簡単でしょう。
FrVaBe 2014年

なぜString.format()を呼び出すのですか?角括弧を取得するだけですか?
ジョルタ

18

Apache Commonsプロジェクトが提供するMapUtilsクラスはMapUtils.debugPrint、マップをきれいに印刷するメソッドを提供します。


私が知っていることではありません。私はグアバ図書館にあまり詳しくありませんが、あったとしても驚かないでしょう。
tlavarea 2012年

これは、少なくともJava 6では必要ありません。AbstractMap#toStringがすでに行っているためです。地図のみの質問:stackoverflow.com/questions/2828252/map-to-string-in-java
Ciro Santilli郝海东冠状病六四事件法轮功

12

System.out.println(Collection c)は、すべてのタイプのコレクションを読み取り可能な形式で既に印刷しています。コレクションにユーザー定義オブジェクトが含まれている場合のみ、コンテンツを表示するにはユーザー定義クラスにtoString()を実装する必要があります。


12

クラスにtoString()を実装します。

これを簡単にするために、Apache Commons ToStringBuilderをお勧めします。それで、あなたはこの種のメソッドを書く必要があります:

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

この種の出力を取得するには:

Person @ 7f54 [name = Stephen、age = 29]

リフレクティブな実装もあります


ToStringBuilderは通常、情報を運ぶBeanとオブジェクトに適していますが、複雑なデータ構造には適していません。スタックオブジェクトがすべての保存されたアイテムを印刷しない場合、これは役に立ちません。
ウリ

2
リフレクションToStringBuilder、HashCodeBuilder、およびEqualsBuilderの使用は非常に効果的ではありません。出力は問題ありませんが、これらのクラスは今週のパフォーマンスのピークになりそうにありません...
Jan Hruby

2
質問では、クラスは組み込みのコレクションであるため、toString()は変更できません。
Rasmus Kaj 2013年


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から「オブジェクト」クラス(1.7以降で使用可能です)

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

出力:1273、123、876、897

もう1つの可能性は、Google Guaveの「MoreObjects」クラスを使用することです。これは、多くの便利なヘルパー関数を提供します。

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

出力:NameOfYourObject = [1273、123、876、897]

グアバのドキュメント


1
Objects.toString()toString()コレクションを呼び出すだけです。あなたの例では、これはおそらくtoString()配列に裏付けられたコレクションでうまく印刷できるのでうまくいきます。
GuyPaddock

3

Apache Commonsの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は、ハードワイヤードフォーマットされていないオブジェクトに対してこの関数を呼び出します。


そして、Eclipseはこれらのクラスをハードワイヤードフォーマットでどのようにフォーマットしますか?それが私が探しているものです。
Elazar Leibovich、

0

コレクションでSopを呼び出すときは注意してくださいConcurrentModification。例外がスローされる可能性があります。toString各コレクションの内部メソッドが内部でコレクションを呼び出すため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

作業を簡略化する方法は2つあります。1. Gsonライブラリをインポートします。2. Lombokを使用します。

どちらもオブジェクトインスタンスから文字列を作成するのに役立ちます。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.