स्प्रिंट जावा में बराबर


284

Printf 1.5 रिलीज के साथ Java में जुड़ गया लेकिन मैं यह नहीं पता लगा सकता कि फ़ाइल के बजाय स्ट्रिंग में आउटपुट कैसे भेजा जाए (जो स्प्रिंट सी में करता है)। क्या किसी को भी यह करना आता है?

जवाबों:



28

तार अपरिवर्तनीय प्रकार हैं। आप उन्हें संशोधित नहीं कर सकते, केवल नए स्ट्रिंग इंस्टेंस लौटा सकते हैं।

उस वजह से, एक आवृत्ति विधि के साथ प्रारूपण करना थोड़ा समझ में आता है, क्योंकि इसे इस तरह कहा जाना चाहिए:

String formatted = "%s: %s".format(key, value);

मूल जावा लेखकों (और .NET लेखकों) ने फैसला किया कि इस स्थिति में एक स्थिर विधि ने और अधिक समझ बना ली है, क्योंकि आप लक्ष्य को संशोधित नहीं कर रहे हैं, बल्कि एक प्रारूप विधि को कॉल करने और एक इनपुट स्ट्रिंग में पास करने के लिए।

यहाँ एक उदाहरण है कि format()एक उदाहरण विधि के रूप में क्यों गूंगा होगा। .NET (और शायद जावा में), Replace()एक उदाहरण विधि है।

तुम यह केर सकते हो:

 "I Like Wine".Replace("Wine","Beer");

हालांकि, कुछ भी नहीं होता है, क्योंकि तार अपरिवर्तनीय हैं। Replace()एक नया स्ट्रिंग वापस करने की कोशिश करता है, लेकिन इसे कुछ भी नहीं सौंपा गया है।

यह आम धोखेबाज़ गलतियों के बहुत सारे कारण हैं:

inputText.Replace(" ", "%20");

फिर, कुछ नहीं होता है, इसके बजाय आपको करना होगा:

inputText = inputText.Replace(" ","%20");

अब, यदि आप समझते हैं कि तार अपरिवर्तनीय हैं, तो यह सही समझ में आता है। यदि आप नहीं करते हैं, तो आप बस भ्रमित हैं। स्थैतिक विधि के रूप में, के लिए उचित स्थान Replace()कहाँ होगा :format()String

 inputText = String.Replace(inputText, " ", "%20");

अब इसमें कोई सवाल नहीं है कि क्या हो रहा है।

असली सवाल यह है कि इन चौखटों के लेखकों ने यह क्यों तय किया कि एक उदाहरण विधि होनी चाहिए, और दूसरी स्थैतिक? मेरी राय में, दोनों को अधिक स्थायी रूप से स्थिर तरीकों के रूप में व्यक्त किया गया है।

आपकी राय के बावजूद, सच्चाई यह है कि आप स्थिर संस्करण का उपयोग करके गलती करने के लिए कम प्रवण हैं, और कोड को समझना आसान है (नो हिडन गॉटचेज़)।

बेशक कुछ तरीके हैं जो उदाहरण के तरीकों के रूप में परिपूर्ण हैं, String.Length () लें

int length = "123".Length();

इस स्थिति में, यह स्पष्ट है कि हम "123" को संशोधित करने की कोशिश नहीं कर रहे हैं, हम सिर्फ इसका निरीक्षण कर रहे हैं, और इसकी लंबाई लौटा रहे हैं। यह एक उदाहरण विधि के लिए एक आदर्श उम्मीदवार है।

अपरिवर्तनीय वस्तुओं पर इंस्टेंस के तरीकों के लिए मेरे सरल नियम:

  • यदि आपको उसी प्रकार का नया उदाहरण वापस करने की आवश्यकता है, तो एक स्थिर विधि का उपयोग करें।
  • अन्यथा, एक आवृत्ति विधि का उपयोग करें।

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

4
प्रारूप स्ट्रिंग के रूप में देखना आमतौर पर "द प्राइस 4 डी है" की तरह है, न कि "% 4 डी" के रूप में, मुझे अभी भी भ्रम की बहुत संभावना है। आपके पास स्थैतिक तरीकों के खिलाफ क्या है? :)
फ्लाईसवाट

44
इस उत्तर का सवाल से कोई लेना देना नहीं है।
स्टीव मैक्लियॉड

2
इसका उत्तर जावा भी नहीं है। .NET
Photodeus

3
-1। डाउनवोट बी / सी यह मूर्त है। और जरूरी नहीं कि अपरिवर्तनीयों के लिए सबसे अच्छी शैली हो। यह शैली सरल विधि कॉल की तुलना में अधिक क्रिया है, विशेष रूप से जंजीर संचालन के लिए। और यह रन-टाइम बहुरूपता को छोड़ देता है क्योंकि यह स्थिर तरीकों को बुला रहा है, जो महत्वपूर्ण है। YMMV।
एंड्रयू जानकी

3

दोनों समाधान प्रिंटो का अनुकरण करते हैं, लेकिन एक अलग तरीके से। उदाहरण के लिए, मान को हेक्स स्ट्रिंग में बदलने के लिए, आपके पास 2 निम्नलिखित समाधान हैं:

  • के साथ format(), निकटतम sprintf():

    final static String HexChars = "0123456789abcdef";
    
    public static String getHexQuad(long v) {
        String ret;
        if(v > 0xffff) ret = getHexQuad(v >> 16); else ret = "";
        ret += String.format("%c%c%c%c",
            HexChars.charAt((int) ((v >> 12) & 0x0f)),
            HexChars.charAt((int) ((v >>  8) & 0x0f)),
            HexChars.charAt((int) ((v >>  4) & 0x0f)),
            HexChars.charAt((int) ( v        & 0x0f)));
        return ret;
    }
  • साथ replace(char oldchar , char newchar), कुछ हद तक तेजी से लेकिन बहुत सीमित:

        ...
        ret += "ABCD".
            replace('A', HexChars.charAt((int) ((v >> 12) & 0x0f))).
            replace('B', HexChars.charAt((int) ((v >>  8) & 0x0f))).
            replace('C', HexChars.charAt((int) ((v >>  4) & 0x0f))).
            replace('D', HexChars.charAt((int) ( v        & 0x0f)));
        ...
  • एक तीसरा समाधान है जिसमें सिर्फ retएक-एक करके चार को जोड़ना है (चार नंबर हैं जो एक-दूसरे को जोड़ते हैं !) जैसे कि:

    ...
    ret += HexChars.charAt((int) ((v >> 12) & 0x0f)));
    ret += HexChars.charAt((int) ((v >>  8) & 0x0f)));
    ...

... लेकिन यह वास्तव में बदसूरत होगा।


सभी महान विचार, लेकिन आपके सहकर्मी के लिए अपने कोड को केवल-लिखने के लिए असंभव कोड में बदल देता है।
बेन

0

आप PrintStream के साथ OutputStream कुछ भी करने के लिए एक Printf कर सकते हैं। किसी तरह इस तरह, एक स्ट्रिंग स्ट्रीम में मुद्रण:

PrintStream ps = new PrintStream(baos);
ps.printf("there is a %s from %d %s", "hello", 3, "friends");
System.out.println(baos.toString());
baos.reset(); //need reset to write new string
ps.printf("there is a %s from %d %s", "flip", 5, "haters");
System.out.println(baos.toString());
baos.reset();

स्ट्रिंग स्ट्रीम को इस बाइट से बनाया जा सकता है।

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