मुद्रण जावा संग्रह अच्छी तरह से (सुंदर उत्पादन वापस नहीं आता है)


211

मैं एक Stack<Integer>वस्तु को अच्छी तरह से प्रिंट करना चाहता हूं जैसा कि एक्लिप्स डिबगर करता है (यानी [1,2,3...]), लेकिन इसे प्रिंट करना out = "output:" + stackइस अच्छे परिणाम को वापस नहीं करता है।

बस स्पष्ट करने के लिए, मैं जावा के अंतर्निहित संग्रह के बारे में बात कर रहा हूं, इसलिए मैं इसे ओवरराइड नहीं कर सकता toString()

मैं स्टैक का एक अच्छा मुद्रण योग्य संस्करण कैसे प्राप्त कर सकता हूं?


7
कम से कम जावा 7 के रूप में, AbstractCollection@toString(और इस तरह String + Stack) पहले से ही इसे प्रिंट करता है जैसे आप चाहते हैं।
सिरो सेंटिल्ली 郝海东 冠状 i i 法轮功 '

जवाबों:


317

आप इसे एक सरणी में बदल सकते हैं और फिर इसे बाहर प्रिंट कर सकते हैं Arrays.toString(Object[]):

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

11
मुझें यह पसंद है। सरल, स्वच्छ। ईमानदार होने के लिए कलेक्शंस को एक सख्त तरीका भी चाहिए, लेकिन यह काम भी करता है।
Tovi7

1
@ Tovi7 यह संभवत: इसलिए नहीं है क्योंकि अधिकांश ओओटीबी संग्रह पहले से ही पढ़ने योग्य स्ट्रींग () प्रदान करते हैं, जबकि सरणियाँ नहीं।
मैक्स नानसी

@ बूशा को कंसोल में स्ट्रिंग को प्रिंट करने के लिए स्टैक को बदलने के लिए O (n) समय भी लगता है और O (n) समय
Zach Langley

stack.toArray()बहुत महंगा, सीपीयू, समय और मेमोरी वार हो सकता है। एक समाधान जो मूल संग्रह / iterable पर पुनरावृत्त करता है, संभवतः कम संसाधन खपत होगा।
AlikElzin-kilaka

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

(जावा 8)


12
अपने को Iterable होना चाहिए <? फैली हुई चैरिटी>
नाथन

3
String.join (",", yourCollection.stream ()। Map (o -> o.toString ())) इकट्ठा करें (कलेक्टर
.toList

@ user1016765 yourCollection.stream().map( o -> o.toString() ).collect( joining(",") ))बेहतर है कि आप इसे बाएं से दाएं पढ़ें, आपको अपने मस्तिष्क में गणना करने के लिए सामने की ओर देखने की जरूरत नहीं है कि मध्यवर्ती सूची के साथ क्या किया जाता है
cdalxndr

18

जावा 8 धाराओं और कलेक्टरों के साथ इसे आसानी से किया जा सकता है:

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

पहले हम बनाने के लिए उपयोग mapकरते Object::toStringहैं Collection<String>और फिर संग्रह में शामिल होने वाले हर आइटम ,को सीमांकक के रूप में शामिल करने के लिए उपयोग करते हैं ।


22
मुझे जवाब से 'आसानी से' शब्द नहीं निकालने के लिए वापस पकड़ना पड़ा; ;-) Collections.toString(stack)आसान होगा।
FrVaBe

String.format () को कॉल क्यों करें? क्या सिर्फ चौकोर कोष्ठक प्राप्त करना है?
जोलता

18

Apache Commons प्रोजेक्ट द्वारा पेश किया गया MapUtils क्लास एक ऐसा MapUtils.debugPrintतरीका प्रदान करता है जो आपके नक्शे को बहुत प्रिंट करेगा।


मेरी जानकारी में नहीं। मैं अमरूद की लाइब्रेरी से बहुत परिचित नहीं हूँ, लेकिन अगर वहाँ था तो मुझे आश्चर्य नहीं होगा।
टालवरिया

इसके लिए कोई ज़रूरत नहीं है, कम से कम जावा 6 में, क्योंकि AbstractMap # toString यह पहले से ही करता है। मानचित्र केवल प्रश्न: stackoverflow.com/questions/2828252/map-to-string-in-java
Ciro Santilli 郝海东 over over over

12

System.out.println (संग्रह c) पहले से ही पठनीय प्रारूप में किसी भी प्रकार के संग्रह को प्रिंट करता है। केवल अगर संग्रह में उपयोगकर्ता परिभाषित ऑब्जेक्ट शामिल हैं, तो आपको सामग्री को प्रदर्शित करने के लिए उपयोगकर्ता परिभाषित वर्ग में toString () को लागू करने की आवश्यकता है।


12

कक्षा पर लागू करना ()।

मैं यह आसान बनाने के लिए Apache Commons ToStringBuilder की सलाह देता हूं । इसके साथ, आपको बस इस प्रकार की विधि लिखनी होगी:

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

इस प्रकार का आउटपुट प्राप्त करने के लिए:

व्यक्ति @ 7f54 [नाम = स्टीफन, उम्र = 29]

एक चिंतनशील कार्यान्वयन भी है ।


ToStringBuilder आमतौर पर सेम और ऑब्जेक्ट्स के लिए अधिक लागू होती है जो जटिल डेटा संरचनाओं के लिए जानकारी लेती हैं। यदि स्टैक ऑब्जेक्ट सभी संग्रहीत आइटम प्रिंट नहीं करता है, तो यह मदद नहीं करेगा।
उरई

2
परावर्तन ToStringBuilder, HashCodeBuilder और EqualsBuilder का उपयोग अत्यधिक अक्षम है। हालांकि उत्पादन ठीक है, ये कक्षाएं सप्ताह के प्रदर्शन के शिखर पर शायद ही हैं ...
जन हर्षि

2
यह प्रश्न स्पष्ट रूप से कहा गया है कि कक्षा एक अंतर्निहित संग्रह है, इसलिए स्ट्रींग () को संशोधित नहीं किया जा सकता है।
रासमस काज


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

एक और संभावना है कि Google Guave के "MoreObjects" वर्ग का उपयोग करें , जो कई उपयोगी सहायक कार्य प्रदान करता है:

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

आउटपुट: NameOfYourObject = [1273, 123, 876, 897]

अमरूद की खुराक


1
Objects.toString()बस toString()संग्रह पर कॉल करता है। आपके उदाहरण में, यह काम करता है क्योंकि संभवतः toString()सरणी-समर्थित संग्रह पर सुंदर रूप से सुंदर प्रिंट होता है।
ग्यूपैडपॉक

3

साथ अपाचे कॉमन्स 3 , आप कॉल करना चाहते

StringUtils.join(myCollection, ",")

3

जावा 8 में

//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()इन दिनों जावा (जावा 7/8) में उपयोगी हैं । इसलिए आपको जो चाहिए उसकी ज़रूरत को पूरा करने के लिए स्ट्रीम ऑपरेशन करने की ज़रूरत नहीं है, बस toStringसंग्रह में आपके मूल्य वर्ग को ओवरराइड करें और आपको जो चाहिए वह प्राप्त करें।

दोनों AbstractMap और AbstractCollection को लागू करने () प्रति तत्व स्ट्रिंग को बुलाकर।

नीचे व्यवहार दिखाने के लिए एक टेस्टक्लास है।

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 प्रिंट कर सकता है। लाभ एक अच्छी तरह से स्वरूपित और पठनीय वस्तु-स्ट्रिंग है, जिसे लागू करने की आवश्यकता के बिना 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

यदि यह आपके स्वयं के संग्रह वर्ग के बजाय एक में निर्मित है, तो आपको इसकी स्ट्रीडिंग विधि को ओवरराइड करने की आवश्यकता है। ग्रहण किसी भी ऑब्जेक्ट के लिए उस फ़ंक्शन को कॉल करता है जिसके लिए यह एक हार्ड-वायर्ड स्वरूपण नहीं है।


और उन वर्गों को ग्रहण प्रारूप w / हार्ड-वायर्ड स्वरूपण कैसे करता है? यही मैं ढूंढ रहा हूं।
एलाजार लीबोविच

0

संग्रह पर एसओपी कॉल करते समय सावधान रहें, यह 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

ऐसे दो तरीके हैं जिनसे आप अपने काम को आसान बना सकते हैं। 1. आयात Gson पुस्तकालय। 2. लोम्बोक का उपयोग करें।

यह दोनों आपको ऑब्जेक्ट इंस्टेंस से स्ट्रिंग बनाने में मदद करते हैं। Gson आपकी वस्तु को पार्स कर देगा, lombok आपकी क्लास ऑब्जेक्ट को स्ट्रींग करने की विधि से आगे निकल जाएगा।

मैंने 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(","));
   }

}

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.