जावा # C स्ट्रिंग के स्टॉर्म.फॉर्म () और स्ट्रिंग। जॉइन ()


111

मुझे पता है कि यह एक नौसिखिया सवाल है, लेकिन क्या जावा में C # के स्ट्रिंग ऑपरेशन के समतुल्य हैं?

विशेष रूप से, मैं बात कर रहा हूँ String.Formatऔर String.Join


तो एक String.format है, लेकिन मुझे अपनी खुद की जॉइन करनी होगी।
उमर कूहीजी

1
शामिल होने के लिए (), मुझे यह उत्तर पसंद है: stackoverflow.com/a/6116469/562139
scorpiodawg

जवाबों:


92

जावा स्ट्रिंग ऑब्जेक्ट में एक formatविधि (1.5 के रूप में) है, लेकिन कोई joinविधि नहीं है।

उपयोगी स्ट्रिंग उपयोगिता विधियों का एक समूह प्राप्त करने के लिए पहले से ही शामिल नहीं है । आप org.apache.commons.lang.StringUtils का उपयोग कर सकते हैं ।


13
Google संग्रह: google-collections.googlecode.com में एक योजक भी है।
रॉन

10
रॉन की टिप्पणी पर FYI करें, कुछ समय पहले Google-Collection का नाम बदलकर Guava कर दिया गया था।
केविन बोर्रिलियन

3
आपको यह उत्तर प्रतिबिंबित करने के लिए अद्यतन करना चाहिए कि जावा 8 एक String.join()विधि का परिचय देता है ।
डंकन जोन्स

46

String.format । शामिल होने के लिए, आपको अपना खुद का लिखना होगा:

 static String join(Collection<?> s, String delimiter) {
     StringBuilder builder = new StringBuilder();
     Iterator<?> iter = s.iterator();
     while (iter.hasNext()) {
         builder.append(iter.next());
         if (!iter.hasNext()) {
           break;                  
         }
         builder.append(delimiter);
     }
     return builder.toString();
 }

उपरोक्त http://snippets.dzone.com/posts/show/91 से आता है


6
अधिक सटीक रूप से: StringBuffer के लिए jdk1.4 और नीचे, StringBuilder के लिए jdk1.5 और उसके बाद, चूंकि उत्तरार्द्ध सिंक्रनाइज़ नहीं है, इसलिए थोड़ा तेज।
VonC

2
दो iter.hasNext () इनवॉइस के मुख्य भाग मैं आमतौर पर परिधि को जोड़ते हैं और फिर "buf.substring (0, buf.length () - delimeter.length ())"।
विल्मंतस बरनौस्कास

2
आप सीमांकक से बचने के लिए जल्दी बाहर निकलने से इसे थोड़ा सा सुव्यवस्थित कर सकते हैं: जबकि (सच) (add_ कैलोरी), अगर ((iter.hasNext ()) ब्रेक; add_delim;}
13ren


29

जावा 8 के रूप में, join()अब स्ट्रिंग वर्ग पर दो वर्ग विधियों के रूप में उपलब्ध है। दोनों ही मामलों में पहला तर्क परिसीमनकर्ता का है।

आप अतिरिक्त तर्कों के रूप में अलग-अलग पासCharSequence कर सकते हैं :

String joined = String.join(", ", "Antimony", "Arsenic", "Aluminum", "Selenium");
// "Antimony, Arsenic, Alumninum, Selenium"

या आप पासIterable<? extends CharSequence> कर सकते हैं :

List<String> strings = new LinkedList<String>();
strings.add("EX");
strings.add("TER");
strings.add("MIN");
strings.add("ATE");

String joined = String.join("-", strings);
// "EX-TER-MIN-ATE"

Java 8 एक नया वर्ग भी जोड़ता है StringJoiner, जिसका उपयोग आप इस तरह कर सकते हैं:

StringJoiner joiner = new StringJoiner("&");
joiner.add("x=9");
joiner.add("y=5667.7");
joiner.add("z=-33.0");

String joined = joiner.toString();
// "x=9&y=5667.7&z=-33.0"


12

आप निम्न प्रकार के लिए चर तर्कों का उपयोग कर सकते हैं:

  String join (String delim, String ... data) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < data.length; i++) {
      sb.append(data[i]);
      if (i >= data.length-1) {break;}
      sb.append(delim);
    }
    return sb.toString();
  }

4

शामिल होने के लिए, मेरा मानना ​​है कि यह थोड़ा कम जटिल लग सकता है:

public String join (Collection<String> c) {
    StringBuilder sb=new StringBuilder();
    for(String s: c)
        sb.append(s);
    return sb.toString();
}

मुझे जावा 5 सिंटैक्स का उपयोग करने की आवश्यकता नहीं है जितना मैं चाहूंगा (विश्वास करें या नहीं, मैं 1.0.x का उपयोग कर रहा हूं) इसलिए मैं थोड़ा कठोर हो सकता हूं, लेकिन मुझे यकीन है कि अवधारणा सही है ।

एडिट एडिशन: स्ट्रिंग एप्स धीमा हो सकता है, लेकिन यदि आप GUI कोड या कुछ शॉर्ट-रनिंग रूटीन पर काम कर रहे हैं, तो यह वास्तव में मायने नहीं रखता है अगर आप .005 सेकंड या .006 लेते हैं, तो यदि आपके पास "joinMe" नामक एक संग्रह है। कि आप एक मौजूदा स्ट्रिंग "लक्ष्य" को जोड़ना चाहते हैं, यह सिर्फ इनलाइन के लिए भीषण नहीं होगा:

for(String s : joinMe)
    target += s;

यह काफी अक्षम (और एक बुरी आदत) है, लेकिन कुछ भी नहीं जिसे आप समझ पाएंगे जब तक कि हजारों तार नहीं हैं या यह एक विशाल लूप के अंदर है या आपका कोड वास्तव में प्रदर्शन महत्वपूर्ण है।

अधिक महत्वपूर्ण बात, यह याद रखना आसान है, छोटा, त्वरित और बहुत पठनीय। प्रदर्शन हमेशा डिज़ाइन विकल्पों में स्वत: विजेता नहीं होता है।


फॉर-लूप सही है, लेकिन आपको इसे एक संग्रह <स्ट्रिंग> भी बनाना चाहिए। यदि आप नहीं करते हैं, तो आपको "for (ऑब्जेक्ट ओ: सी)" कहना होगा, क्योंकि आप गारंटी नहीं दे सकते कि सी में सब कुछ एक स्ट्रिंग था।
माइकल मायर्स

अच्छी बात है, मैं जेनरिक के साथ और भी अधिक कठोर हूँ। मैं इसे संपादित करूँगा।
बिल K

इनरनेटिंग इनलाइन: स्ट्रिंग + स्ट्रिंग + स्ट्रिंग, संकलक वास्तव में स्ट्रिंग को जोड़ने के लिए स्ट्रिंग का उपयोग करता है। मुझे आश्चर्य है कि अगर आपके पास लूप विधि है, तो आप दूसरे स्थान पर हैं, क्या कंपाइलर ऐसा करेगा।
स्पेंसर कोरम्स

@ स्पेंसर के: यह एक स्ट्रिंगब्यूलर का उपयोग करता है, लेकिन यह प्रत्येक पुनरावृत्ति के लिए एक नया बनाता है (शायद ही सबसे कुशल विधि, लेकिन फिर संकलक को कैसे जानना चाहिए?)। मुझे नहीं पता कि JIT कंपाइलर रनटाइम में इसे ऑप्टिमाइज़ कर सकता है या नहीं।
माइकल मायर्स

2
अरे रुको। क्या आप बात कर रहे हैं + =? हाँ, यह बेकार है। मेरे उत्तर में वर्तमान में लूप और परिशिष्ट StringBuilder का उपयोग करता है और यही मैं बात कर रहा हूं। हालांकि + = ने बहुत सुधार किया है आप वास्तव में इसे लूप के अंदर उपयोग नहीं करना चाहते हैं - इतना नहीं कि यह छोटी गाड़ी है लेकिन इसमें यह बकवास की तरह प्रदर्शन कर सकता है (बग आमतौर पर प्रदर्शन के मुद्दों के लिए इस्तेमाल किया जाने वाला शब्द नहीं है - कम से कम नहीं मेरी प्रोग्रामिंग के 20 वर्षों में)। इसके अलावा JIT इसे बहुत बेहतर बना सकता है - लेकिन मैं उस पर भरोसा नहीं करूंगा।
बिल K

4

यहाँ एक बहुत ही सरल उत्तर है। +=चूंकि यह कम कोड का उपयोग करता है और अनुकूलक को इसे आपके लिए परिवर्तित करने StringBuilderदेता है। इस पद्धति का उपयोग करते हुए, आपको अपने लूप (प्रदर्शन सुधार) में कोई "अंतिम" चेक नहीं करना है और आपको अंत में किसी भी सीमांकक को अलग करने के बारे में चिंता करने की आवश्यकता नहीं है।

        Iterator<String> iter = args.iterator();
        output += iter.hasNext() ? iter.next() : "";
        while (iter.hasNext()) {
            output += "," + iter.next();
        }

1
बहुत सुंदर समाधान, 3 पार्टी पुस्तकालयों को शामिल नहीं!
डेनिस इसकीकोविच 17

2

मैं एक पूरी अपाचे लाइब्रेरी को एक साधारण जॉइन फंक्शन जोड़ने के लिए आयात नहीं करना चाहता था, इसलिए यहाँ मेरा हैक है।

    public String join(String delim, List<String> destinations) {
        StringBuilder sb = new StringBuilder();
        int delimLength = delim.length();

        for (String s: destinations) {
            sb.append(s);
            sb.append(delim);
        }

        // we have appended the delimiter to the end 
        // in the previous for-loop. Let's now remove it.
        if (sb.length() >= delimLength) {
            return sb.substring(0, sb.length() - delimLength);
        } else {
            return sb.toString();
        }
    }

@MrSnowflake क्या मानक स्ट्रिंग बिल्डर में एक विधि है "removeCharAt (int index)" इसका संस्करण Im पर नहीं दिख रहा है चल रहा है
NSjonas

@ सोंसोनस - हाँ, मेरे उत्तर के लिए उसका संपादन गलत है। removeCharAtमौजूद नहीं है, और पूरे समारोह अब एक स्ट्रिंग रिटर्न ... इसे ठीक करेंगे।
मार्टिन कोंकणी

जब आपके पास ... यह वर्तमान समाधान एक "सीमा से बाहर सूचकांक को फेंक देगा यदि आप एक खाली सूची में पास होते हैं"
एनएसजोनस

अगर एक से अधिक वर्ण हैं, तो दाईं ओर ट्रिम करने के लिए एक संपादन करें। एक ऐसा मुद्दा भी तय किया जहां आप अंतिम चरित्र को ट्रिम कर रहे थे, न कि पहले जैसा कि आपको वास्तव में जरूरी था
NSjonas

प्रतिक्रिया के लिए Thx। अपडेट किया गया।
मार्टिन कोनसेनी

1

यदि आप एक में कई तार जुड़ना चाहते हैं (संक्षिप्त), तो आपको स्ट्रिंग स्ट्रिंग का उपयोग करना चाहिए। यह उपयोग करने से कहीं बेहतर है

for(String s : joinMe)
    target += s;

StringBuffer पर एक मामूली प्रदर्शन जीत भी है, क्योंकि StringBuilder सिंक्रनाइज़ेशन का उपयोग नहीं करता है।

इस तरह एक सामान्य प्रयोजन उपयोगिता विधि के लिए, यह (अंततः) कई स्थितियों में कई बार कहा जाएगा, इसलिए आपको इसे कुशल बनाना चाहिए और कई क्षणिक वस्तुओं को आवंटित नहीं करना चाहिए। हमने कई, कई अलग-अलग जावा एप्स को प्रोफाइल किया है और लगभग हमेशा पाया है कि स्ट्रिंग कॉन्फैक्शन और स्ट्रिंग / चार [] आवंटन समय / मेमोरी का एक महत्वपूर्ण हिस्सा लेते हैं।

हमारा पुन: प्रयोज्य संग्रह -> स्ट्रिंग विधि पहले आवश्यक परिणाम के आकार की गणना करती है और फिर उस प्रारंभिक आकार के साथ एक स्ट्रिंगबर्स्ट बनाता है; यह आवेषण को जोड़ते समय उपयोग किए जाने वाले आंतरिक चार [] के दोहरीकरण / नकल से बचा जाता है।


पुन: पूर्व-गणना आकार: जब वह काम करता है, तो यह बहुत अच्छा है। यह हमेशा संभव नहीं है। मुझे याद है कि हर बार बफर साइज़ को दोगुना करना (या वास्तव में किसी निश्चित कारक द्वारा गुणा करना) एन लॉग एन प्रदर्शन जैसा कुछ देता है, जो वास्तव में बुरा नहीं है। सामान्य स्थिति में, विकल्प उन सभी तारों की एक सूची बनाना है, जिन्हें आप संक्षिप्त करने की योजना बना रहे हैं। यदि आप एक ArrayList का उपयोग करते हैं, तो आपको फिर से नकल मिल जाती है (जब तक कि आपको अपने अनुक्रम की लंबाई पहले से पता न हो) और यदि आप LinkedList का उपयोग करते हैं, तो यह नोड ऑब्जेक्ट्स के साथ अधिक रैम और कचरा संग्रह का उपयोग करता है। कभी-कभी आप जीत नहीं सकते। कोशिश करो!
इयान

उपरोक्त उदाहरण / पूछताछ में शामिल होने के लिए स्ट्रिंग्स के कुछ आदेशित संग्रह या सरणी को ग्रहण किया गया। इसके अलावा, आकार को पूर्ववर्ती करके, आप अतिरिक्त अप्रयुक्त वर्णों से बचते हैं, जो आंतरिक चार [] सरणी वृद्धि आमतौर पर परिणाम देते हैं।
djb

1

मैंने खुद लिखा:

public static String join(Collection<String> col, String delim) {
    StringBuilder sb = new StringBuilder();
    Iterator<String> iter = col.iterator();
    if (iter.hasNext())
        sb.append(iter.next().toString());
    while (iter.hasNext()) {
        sb.append(delim);
        sb.append(iter.next().toString());
    }
    return sb.toString();
}

लेकिन CollectionJSP द्वारा समर्थित नहीं है, इसलिए टैग फ़ंक्शन के लिए मैंने लिखा है:

public static String join(List<?> list, String delim) {
    int len = list.size();
    if (len == 0)
        return "";
    StringBuilder sb = new StringBuilder(list.get(0).toString());
    for (int i = 1; i < len; i++) {
        sb.append(delim);
        sb.append(list.get(i).toString());
    }
    return sb.toString();
}

और .tldफ़ाइल में डाल दिया :

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee"
    <function>
        <name>join</name>
        <function-class>com.core.util.ReportUtil</function-class>
        <function-signature>java.lang.String join(java.util.List, java.lang.String)</function-signature>
    </function>
</taglib>

और JSP फ़ाइलों में इसका उपयोग करें:

<%@taglib prefix="funnyFmt" uri="tag:com.core.util,2013:funnyFmt"%>
${funnyFmt:join(books, ", ")}

0

StringUtils Apache Commons Lang लाइब्रेरी में एक बहुत ही उपयोगी क्लास है।


8
शायद आपने ध्यान नहीं दिया कि स्वीकृत जवाब, 8 महीने पहले पोस्ट किया गया था, पहले से ही वही जानकारी शामिल है; stackoverflow.com/questions/187676/string-operations-in-java/…
जोनिक


0

मैं String.Join के अत्यधिक जटिल कार्यान्वयन को देखता हूं। यदि आपके पास जावा 1.8 नहीं है, और आप एक नया पुस्तकालय आयात नहीं करना चाहते हैं तो नीचे के कार्यान्वयन को पर्याप्त होना चाहिए।

public String join(Collection<String> col, String delim) {
    StringBuilder sb = new StringBuilder();
    for ( String s : col ) {
        if ( sb.length() != 0 ) sb.append(delim);
        sb.append(s);
    }
    return sb.toString();
}

-1
ArrayList<Double> j=new ArrayList<>; 
j.add(1);
j.add(.92);
j.add(3); 
String ntop=j.toString(); //ntop= "[1, 0.92, 3]" 

तो मूल रूप से, स्ट्रिंग ntop पूरे संग्रह का मान अल्पविराम विभाजक और कोष्ठक के साथ संग्रहीत करता है।


1
मुझे यकीन नहीं है कि इस सवाल का क्या हिस्सा है? जब तक आप स्ट्रिंग के बिट्स को थोड़ा सा सरणी में जोड़ने की योजना नहीं बनाते हैं, तब तक यह स्ट्रिंगिंगफॉर्म नहीं है, और [1,0.92,3] सामान्य स्ट्रिंग के रूप में बहुमुखी नहीं है।
उमर कूहेजी

-8

मैं दो स्ट्रिंग में शामिल होने के लिए स्ट्रिंग स्ट्रिंग संचालक "+" का उपयोग करूंगा। s1 += s2;


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