जावा 8 का उपयोग करके वस्तुओं की सूची को स्ट्रिंग () विधि से प्राप्त स्ट्रिंग में परिवर्तित करना


206

Java 8. Eg में बहुत सी उपयोगी नई चीजें हैं, मैं वस्तुओं की एक सूची पर एक धारा के साथ पुनरावृति कर सकता हूं और फिर एक विशिष्ट क्षेत्र से मूल्यों का योग कर सकता हूं Object। उदाहरण के लिए

public class AClass {
  private int value;
  public int getValue() { return value; }
}

Integer sum = list.stream().mapToInt(AClass::getValue).sum();

इस प्रकार, मैं पूछ रहा हूं कि क्या कोई ऐसा तरीका है जो किसी एकल पंक्ति में इंस्टेंसेस से विधि Stringके आउटपुट को तैयार करता है toString()

List<Integer> list = ...

String concatenated = list.stream().... //concatenate here with toString() method from java.lang.Integer class

मान लीजिए कि listपूर्णांक शामिल हैं 1, 2और 3, मुझे उम्मीद है कि concatenatedहै "123"या "1,2,3"


जवाबों:


369

एक सरल तरीका यह है कि अपनी सूची आइटम को एक में जोड़ें StringBuilder

   List<Integer> list = new ArrayList<>();
   list.add(1);
   list.add(2);
   list.add(3);

   StringBuilder b = new StringBuilder();
   list.forEach(b::append);

   System.out.println(b);

आप भी आज़मा सकते हैं:

String s = list.stream().map(e -> e.toString()).reduce("", String::concat);

स्पष्टीकरण: नक्शा स्ट्रींग स्ट्रीम में इंटेगर स्ट्रीम को परिवर्तित करता है, फिर सभी तत्वों के संयोजन के रूप में इसे कम किया जाता है।

नोट: यह वह है normal reductionजो O (n 2 ) में करता है

बेहतर प्रदर्शन के लिए F StringBuilderया mutable reductionBöller के उत्तर का उपयोग करें।

String s = list.stream().map(Object::toString).collect(Collectors.joining(","));

Ref: स्ट्रीम में कमी


2
हाँ, एक इनलाइन समाधान नहीं है, बल्कि एक समाधान है।
mat_boy

वह नहीं मिला। आप क्या उम्मीद कर रहे हैं
शीलिंगा

2
मुझे समझ नहीं आ रहा है कि "सामान्य कमी जो O (n2) में प्रदर्शन करती है"। मुझे यह "ओ (एन) की तरह" दिखता है ...
डेटाकी

2
@datahaki मैं एक जावा लड़का नहीं हूं, लेकिन मुझे लगता है कि पुनरावृत्ति स्ट्रिंग में कमी (कमी) को प्रत्येक पुनरावृत्ति पर सरणी (पुनः) आवंटन की आवश्यकता होती है, जो इसे O (n ^ 2) बनाता है। joinदूसरी तरफ एक एकल सरणी का प्रचार करेगा, जो इसे पॉप करने से पहले अंतिम स्ट्रिंग को स्टोर करने के लिए पर्याप्त है, जिससे यह ओ (एन) हो जाएगा।
एली कोरविगो

2
बहुत अच्छी टिप। शायद आप "::" संकेतन का उपयोग करके सरल कर सकते हैं। तो, list.stream().map(Object::toString).reduce("", String::concat)। इस्तेमाल करना map e-> e.toString()थोड़ा बेमानी है।
e2a

194

joiningएपीआई में एक कलेक्टर है। यह एक स्थिर विधि है Collectors

list.stream().map(Object::toString).collect(Collectors.joining(","))

आवश्यक कॉल के कारण सही नहीं है toString, लेकिन काम करता है। विभिन्न परिसीमन संभव हैं।


7
पूर्णता के लिए: काम करने के लिए उस सटीक कोड को प्राप्त करने के लिए, आपकोimport static java.util.stream.Collectors.joining;
महदी

7
हमें मानचित्रण और स्पष्ट `स्ट्रींग 'की आवश्यकता क्यों है? यदि कलेक्टर स्ट्रिंग तत्वों की अपेक्षा कर रहा है तो रूपांतरण को अंतर्निहित रूप से लागू किया जाना चाहिए, नहीं ?!
बेसल शिशानी

10

बस के मामले में किसी को भी जावा 8 के बिना यह करने की कोशिश कर रहा है, एक बहुत अच्छी चाल है। List.toString () पहले से ही एक संग्रह देता है जो इस तरह दिखता है:

[1,2,3]

आपकी विशिष्ट आवश्यकताओं के आधार पर, यह तब तक संसाधित किया जा सकता है, जब तक आप चाहते हैं कि जब तक आपकी सूची आइटम में [] या नहीं हो।

उदाहरण के लिए:

list.toString().replace("[","").replace("]","") 

या यदि आपके डेटा में वर्ग कोष्ठक हो सकते हैं:

String s=list.toString();
s = s.substring(1,s.length()-1) 

आप एक बहुत ही उचित उत्पादन मिलेगा।

प्रत्येक पंक्ति पर एक सरणी आइटम इस तरह बनाया जा सकता है:

list.toString().replace("[","").replace("]","").replaceAll(",","\r\n")

मैंने इस तकनीक का उपयोग एक छोटे से ऐप में सूची से html टूलटिप्स बनाने के लिए किया, जैसे कुछ:

list.toString().replace("[","<html>").replace("]","</html>").replaceAll(",","<br>")

यदि आपके पास एक सरणी है तो इसके बजाय Arrays.asList (सूची) .toString () से शुरू करें

मैं पूरी तरह से इस तथ्य का मालिक हूं कि यह इष्टतम नहीं है, लेकिन यह उतना अयोग्य नहीं है जितना आप सोच सकते हैं और पढ़ने और समझने के लिए बहुत सरल हैं। यह, हालांकि, काफी अनम्य है - विशेष रूप से तत्वों को अलग करने की कोशिश न करें यदि आपके डेटा में अल्पविराम हो सकते हैं और यदि आपके डेटा में वर्ग कोष्ठक हैं, तो सबस्ट्रिंग संस्करण का उपयोग कर सकते हैं, लेकिन संख्याओं के लिए यह बहुत अधिक है। उत्तम।


हालांकि यह आमतौर पर काम करेगा, इसकी गारंटी नहीं है - Listकी संरचना को लागू नहीं करता है toString()AbstractCollectionहालाँकि, डिफ़ॉल्ट रूप से इस संरचना का उपयोग करता है, और मुझे लगता है कि Listजावा एसई में सभी सामान्य प्रयोजन कार्यान्वयन समान हैं। एक के उदाहरण के रूप org.springframework.util.AutoPopulatingListमें , वसंत में लागू नहीं होता है toString()और इस प्रकार उदाहरण के लिए " org.springframework.util.AutoPopulatingList@170a1" वापस आ जाएगा ।
एम। जस्टिन

Arrays.toString()एक बेहतर विकल्प होगा Arrays.asList(list).toString(), क्योंकि इसे एक समतुल्य स्ट्रिंग को लौटाने के लिए परिभाषित किया गया है, यह अधिक संक्षिप्त है, और इसके लिए अतिरिक्त ऑब्जेक्ट निर्माण की आवश्यकता नहीं है।
एम। जस्टिन

@ M.Justin इस उत्तर के सरणी भाग के लिए एक बुरा बिंदु नहीं है, लेकिन एक सादे "सूची" के बारे में क्या? आप वास्तव में उस पर Arrays.toString () का उपयोग नहीं कर सकते। आप इस तकनीक का उपयोग करने का सुझाव कैसे देंगे जैसे कि आपके द्वारा उल्लिखित AutoPopulatingList? हो सकता है: नया ArrayList (autoPopulatingList) .toString ()? या मुझे लगता है कि आप इसे एक सरणी में बदल सकते हैं। हो सकता है कि अगर आप ऐसी समस्या में भाग गए, तो आपको उम्मीद करनी चाहिए कि आप 1.8 या उसके बाद के हैं और इस धागे में अन्य उत्तरों में से एक का उपयोग कर सकते हैं ...
बिल K

5

अन्य उत्तर ठीक हैं। हालाँकि, आप ArrayList के रूप में तत्वों को वापस करने के लिए Stream.collect () के पैरामीटर के रूप में कलेक्टरों को भी पारित कर सकते हैं ।

System.out.println( list.stream().map( e -> e.toString() ).collect( toList() ) );

यदि आप System.out.print(ln) (list)का उपयोग करते हैं तो toString()यह सूची को प्रिंट करने के लिए तत्वों की विधि का उपयोग करेगा । तो, कोड का यह टुकड़ा सिर्फ वही दोहरा रहा है जो toStringसूची के अंदर होता है ।
शिरकाम

1
जब तक आप स्थैतिक आयात नहीं कर रहे हों, तब तक कलेक्टर.ऑटलिस्ट () होना चाहिए।
mwieczorek

हां ... मैंने उदाहरण के लिए स्थैतिक आयात किया। मैंने कहा, "कलेक्टर ।toList ()" जवाब के शरीर में ...?)
एडी बी


2

स्ट्रिंग एपीआई में "स्ट्रिंग की सूची में शामिल होने" के लिए एक तरीका है, आपको स्ट्रीम की भी आवश्यकता नहीं है।

List<String> myStringIterable = Arrays.asList("baguette", "bonjour");

String myReducedString = String.join(",", myStringIterable);

// And here you obtain "baguette,bonjour" in your myReducedString variable

1
List<String> list = Arrays.asList("One", "Two", "Three");
    list.stream()
            .reduce("", org.apache.commons.lang3.StringUtils::join);

या

List<String> list = Arrays.asList("One", "Two", "Three");
        list.stream()
                .reduce("", (s1,s2)->s1+s2);

यह दृष्टिकोण आपको वस्तुओं की सूची से एक स्ट्रिंग परिणाम बनाने की अनुमति देता है उदाहरण

List<Wrapper> list = Arrays.asList(w1, w2, w2);
        list.stream()
                .map(w->w.getStringValue)
                .reduce("", org.apache.commons.lang3.StringUtils::join);

यहां कम फ़ंक्शन आपको कुछ प्रारंभिक मूल्य रखने की अनुमति देता है, जिसके लिए आप नए स्ट्रिंग को जोड़ना चाहते हैं उदाहरण:

 List<String> errors = Arrays.asList("er1", "er2", "er3");
            list.stream()
                    .reduce("Found next errors:", (s1,s2)->s1+s2);

1

Shail016 और bpedroso उत्तर ( https://stackoverflow.com/a/24883180/2832140 ) में सुझाए गए दोनों दृष्टिकोणों का परीक्षण , एक लूप के भीतर सरल StringBuilder+ , की तुलना में बहुत तेज़ी से निष्पादित होता हैappend(String)forlist.stream().map([...]

उदाहरण: यह कोड एक Map<Long, List<Long>>बनाता है एक जौन स्ट्रिंग के माध्यम से चलता है , का उपयोग कर list.stream().map([...]:

if (mapSize > 0) {
    StringBuilder sb = new StringBuilder("[");

    for (Map.Entry<Long, List<Long>> entry : threadsMap.entrySet()) {

        sb.append("{\"" + entry.getKey().toString() + "\":[");
        sb.append(entry.getValue().stream().map(Object::toString).collect(Collectors.joining(",")));
    }
    sb.delete(sb.length()-2, sb.length());
    sb.append("]");
    System.out.println(sb.toString());
}

मेरे देव वीएम पर, परीक्षण निष्पादित करने के लिए आमतौर पर कनिष्ठ 0.35 और 1.2 सेकंड के बीच होता है। इस कोड का उपयोग करते समय, यह 0.15 और 0.33 सेकंड के बीच लेता है:

if (mapSize > 0) {
    StringBuilder sb = new StringBuilder("[");

    for (Map.Entry<Long, List<Long>> entry : threadsMap.entrySet()) {

        sb.append("{\"" + entry.getKey().toString() + "\":[");

        for (Long tid : entry.getValue()) {
            sb.append(tid.toString() + ", ");
        }
        sb.delete(sb.length()-2, sb.length());
        sb.append("]}, ");
    }
    sb.delete(sb.length()-2, sb.length());
    sb.append("]");
    System.out.println(sb.toString());
}

0

क्या हम यह कोशिश कर सकते हैं

public static void main(String []args){
        List<String> stringList = new ArrayList<>();
        for(int i=0;i< 10;i++){
            stringList.add(""+i);
        }
        String stringConcated = String.join(",", stringList);
        System.out.println(stringConcated);

    }

0
String actual = list.stream().reduce((t, u) -> t + "," + u).get();

7
आमतौर पर अपनी पोस्ट में एक स्पष्टीकरण जोड़ना एक अच्छा विचार है जो इस बारे में बात करता है कि कोड कैसे काम करता है। यह नए डेवलपर्स को यह समझने की अनुमति देता है कि कोड क्या करता है।
कालेब क्लेवेटर

1
@CalebKleveter यह एक Listको कम करता है Stringऔर प्रत्येक तत्व को अल्पविराम ( ,) के साथ अलग करता है ।
जो अल्मोर

2
यदि सूची सूची स्ट्रिंग है तो आपका समाधान केवल काम करता है। ओपी ने ऐसी कक्षा निर्दिष्ट नहीं की। उनके प्रश्न में भी एक सूची <Integer> इंगित की गई है। आपका कोड उस स्थिति में संकलन नहीं करता है।
RubioRic

0

पूर्णांक की एक धारा को एक स्ट्रिंग में बदलने के लिए मैं स्ट्रीम एपीआई का उपयोग करने जा रहा हूं। प्रदान किए गए कुछ उत्तरों के साथ समस्या यह है कि वे स्ट्रिंग बिल्डिंग के कारण O (n ^ 2) रनटाइम का उत्पादन करते हैं। एक बेहतर उपाय यह है कि स्ट्रिंगबर्ल का उपयोग किया जाए, और फिर अंतिम चरण के रूप में तार को एक साथ जोड़ दिया जाए।

//              Create a stream of integers 
    String result = Arrays.stream(new int[]{1,2,3,4,5,6 })                
            // collect into a single StringBuilder
            .collect(StringBuilder::new, // supplier function
                    // accumulator - converts cur integer into a string and appends it to the string builder
                    (builder, cur) -> builder.append(Integer.toString(cur)),
                    // combiner - combines two string builders if running in parallel
                    StringBuilder::append) 
            // convert StringBuilder into a single string
            .toString();

आप एक स्ट्रिंग के लिए ऑब्जेक्ट के संग्रह को परिवर्तित करके इस प्रक्रिया को एक कदम आगे ले जा सकते हैं।

// Start with a class definition
public static class AClass {
    private int value;
    public int getValue() { return value; }
    public AClass(int value) { this.value = value; }

    @Override
    public String toString() {
        return Integer.toString(value);
    }
}

// Create a stream of AClass objects
        String resultTwo = Arrays.stream(new AClass[]{
                new AClass(1),
                new AClass(2),
                new AClass(3),
                new AClass(4)
        })
                // transform stream of objects into a single string
                .collect(StringBuilder::new,
                        (builder, curObj) -> builder.append(curObj.toString()),
                        StringBuilder::append
                )
            // finally transform string builder into a single string
            .toString();

-1

जावा 8+ के साथ

String s = Arrays.toString(list.stream().toArray(AClass[]::new));

सबसे कुशल नहीं है, लेकिन यह कोड की एक छोटी राशि के साथ एक समाधान है।


-2

इसके अलावा, आप इस तरह कर सकते हैं।

    List<String> list = Arrays.asList("One", "Two", "Three");
    String result = String.join(", ", list);
    System.out.println(result);

यदि सूची सूची स्ट्रिंग है तो आपका समाधान केवल काम करता है। ओपी ने ऐसी कक्षा निर्दिष्ट नहीं की। उनके प्रश्न में भी एक सूची <Integer> इंगित की गई है।
RubioRic
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.