परिवर्तित सूची <Integer> से सूची <स्ट्रिंग>


105

मेरे पास पूर्णांकों की एक सूची है, List<Integer>और मैं सभी पूर्णांक वस्तुओं को स्ट्रिंग्स में बदलना चाहता हूं, इस प्रकार एक नए के साथ समाप्त हो रहा हूं List<String>

स्वाभाविक रूप से, मैं प्रत्येक पूर्णांक List<String>के लिए कॉल करने वाली सूची के माध्यम से एक नया और लूप बना सकता हूं String.valueOf(), लेकिन मैं सोच रहा था कि क्या ऐसा करने का एक बेहतर (पढ़ें: अधिक स्वचालित ) तरीका था?

जवाबों:


77

जहां तक ​​मुझे पता है, ऐसा करने के लिए इटरेट और इंस्टेंटेज ही एकमात्र तरीका है। कुछ और (संभावित संभावित मदद के लिए, क्योंकि मुझे यकीन है कि आप जानते हैं कि यह कैसे करना है):

List<Integer> oldList = ...
/* Specify the size of the list up front to prevent resizing. */
List<String> newList = new ArrayList<>(oldList.size());
for (Integer myInt : oldList) { 
  newList.add(String.valueOf(myInt)); 
}

जब यह सरल होता है, तो इसे सुंदरता कहा जाता है।
एल्बेक

1
मूल पोस्टर से प्रतीत होता है कि उन्होंने इसके बारे में सोचा था लेकिन इस समाधान को बहुत जटिल या थकाऊ माना। लेकिन मैं कल्पना करना मुश्किल है कि क्या आसान हो सकता है। हां, कभी-कभी आपको नौकरी पाने के लिए कोड की 3 या 4 लाइनें लिखनी पड़ती हैं।
Jay

लेकिन यह आपको ArrayList से बांधता है। क्या इसे मूल सूची के समान कार्यान्वयन का उपयोग करके किया जा सकता है?
अलियनोस-

@Andreas oldList.getClass ()। NewInstance () करेंगे
मार्टिनेज

96

गुवा-प्रोजेक्ट से Google संग्रह का उपयोग करते हुए , आप सूची वर्ग transformमें विधि का उपयोग कर सकते हैं

import com.google.common.collect.Lists;
import com.google.common.base.Functions

List<Integer> integers = Arrays.asList(1, 2, 3, 4);

List<String> strings = Lists.transform(integers, Functions.toStringFunction());

Listलौट आने तक transformएक है दृश्य समर्थन की सूची पर - परिवर्तन तब्दील सूची में प्रत्येक एक्सेस पर लागू किया जाएगा।

इस बात Functions.toStringFunction()से अवगत रहें कि NullPointerExceptionजब नल को लागू किया जाएगा , तो इसे केवल तभी उपयोग करें जब आप सुनिश्चित हों कि आपकी सूची में शून्य नहीं होगा।


1
यह अच्छा होगा यदि कार्य के बगल में अधिक तैयार कार्य हों
।toStringFunction

1
साफ है, लेकिन शायद उतना तेज़ नहीं है .. 1 अतिरिक्त फ़ंक्शन प्रति मान?
h3xStream

3
हॉटस्पॉट इनलाइन फ़ंक्शन कॉल कर सकता है - इसलिए यदि इसे पर्याप्त कहा जाता है, तो इससे कोई फर्क नहीं पड़ना चाहिए।
बेन लिंग्स

3
मैं इसे कम नहीं करता क्योंकि यह वास्तव में एक समाधान है। लेकिन लोगों को इस तरह के सरल कार्य को हल करने के लिए एक पुस्तकालय निर्भरता को जोड़ने के लिए प्रोत्साहित करना मेरे लिए एक नहीं है।
एस्टानी

1
अच्छा समाधान यदि आप पहले से ही हमारे समाधान में अमरूद का उपयोग कर रहे हैं।
दुदिंध-समर्पण

86

जावा के लिए समाधान 8. अमरूद एक से थोड़ा अधिक, लेकिन कम से कम आपको एक पुस्तकालय स्थापित करने की आवश्यकता नहीं है।

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

//...

List<Integer> integers = Arrays.asList(1, 2, 3, 4);
List<String> strings = integers.stream().map(Object::toString)
                                        .collect(Collectors.toList());

1
हालांकि यह toStringउदाहरण के लिए थोड़ा लंबा है , यह अमरूद के फ़ंक्शंस लाइब्रेरी द्वारा समर्थित नहीं रूपांतरणों के लिए छोटा है। कस्टम फ़ंक्शंस अभी भी आसान हैं, लेकिन यह काफी अधिक कोड है तो यह जावा 8 स्ट्रीम
lightswitch05

40

आप जो कर रहे हैं वह ठीक है, लेकिन यदि आपको 'जावा-इट-अप' की आवश्यकता महसूस होती है, तो आप अपाचे कॉमन्स से एक ट्रांसफॉर्मर और कलेक्ट विधि का उपयोग कर सकते हैं , जैसे:

public class IntegerToStringTransformer implements Transformer<Integer, String> {
   public String transform(final Integer i) {
      return (i == null ? null : i.toString());
   }
}

..और फिर..

CollectionUtils.collect(
   collectionOfIntegers, 
   new IntegerToStringTransformer(), 
   newCollectionOfStrings);

1
CollectionUtils.collect (collectionOfIntegers, new org.apache.commons.collections.functors.StringValueTransformer ()); लेकिन, StringValueTransformer String.valueOf का उपयोग करता है ...
कन्नन एकनाथ

5
जब तक अपाचे संग्रह पर नया काम नहीं किया गया है, वे जेनरिक नहीं करते हैं।
कित्सुएनएमजी

1
यह वास्तव में जावा-इंग-इट डाउन है। यह मुहावरेदार जावा नहीं है, और कार्यात्मक प्रोग्रामिंग की तरह अधिक है। शायद जब हम जावा 8 में बंद हो जाते हैं तो क्या आप इसे मुहावरेदार जावा कह सकते हैं।
क्रिस्टोफर हैमरस्ट्रॉम्

आप निश्चित रूप से जेनरिक के समर्थन के लिए (पुराने 3.x संग्रह नहीं) के लिए Collections4 का उपयोग करना चाहते हैं: commons.apache.org/proper/commons-collections/apidocs/org/…
JRA_TLL

एक नए वर्ग को परिभाषित करने के लिए "अधिक ओओपी या मुहावरेदार" होना ... मैं नहीं देखता कि यह प्रत्येक लूप के लिए सरल से बेहतर कैसे है। इसके लिए अधिक कोड की आवश्यकता होती है और कार्यक्षमता को दूर ले जाता है (जिसे अनाम वर्गों द्वारा कम किया जा सकता है, लेकिन फिर भी)। यह कार्यात्मक शैली केवल तब उपयोगी होने लगती है जब जावा के 8 के बाद से एक सभ्य वाक्य रचना (यानी लैम्ब्डा एक्सप्रेशन), जैसे कि कार्यात्मक भाषाओं ने इसे दशकों तक प्रदान किया है।
TheOperator

9

String.valueOf का स्रोत यह दिखाता है:

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

ऐसा नहीं है कि यह बहुत मायने रखता है, लेकिन मैं स्टर्लिंग का उपयोग करूंगा।


9

String.valueOf का उपयोग करने के बजाय मैं .toString () का उपयोग करूँगा; यह @ johnathan.holland द्वारा वर्णित कुछ ऑटो मुक्केबाजी से बचा जाता है

Javadoc का कहना है कि valueOf, Integer.toString () जैसी ही चीज़ लौटाती है।

List<Integer> oldList = ...
List<String> newList = new ArrayList<String>(oldList.size());

for (Integer myInt : oldList) { 
  newList.add(myInt.toString()); 
}

टॉम हॉन्टिन द्वारा 'जीत' जवाब में बताया गया है, कोई सूची <स्ट्रिंग> नहीं कर सकता क्योंकि यह केवल एक इंटरफ़ेस है।
स्टु थॉम्पसन

हे मैं जानता था कि। बस मैंने कोशिश किए बिना कोड लिख दिया। मैं इसे अपने उत्तर में ठीक करूंगा।
ScArcher2

9

यहां गैर-जेडीके लाइब्रेरी के साथ धोखा किए बिना एक-लाइनर समाधान है।

List<String> strings = Arrays.asList(list.toString().replaceAll("\\[(.*)\\]", "$1").split(", "));

7

एक और समाधान अमरूद और जावा 8 का उपयोग कर

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<String> strings = Lists.transform(numbers, number -> String.valueOf(number));

3

कोर जावा, और जेनेरिक-इफाइड नहीं है, लेकिन लोकप्रिय जकार्ता कॉमन्स संग्रह पुस्तकालय में इस तरह के कार्य के लिए कुछ उपयोगी सार हैं। विशेष रूप से, पर एकत्रित तरीकों पर एक नज़र है

CollectionUtils

यदि आप पहले से ही अपनी परियोजना में कॉमन्स संग्रह का उपयोग कर रहे हैं, तो कुछ पर विचार करें।


4
अपाचे कलेक्शंस का इस्तेमाल कभी न करें। वे पुराने, पुराने, टाइप-सुरक्षित नहीं हैं, और खराब लिखे गए हैं।
कित्सुएनएमजीएम

3

Jsight के जवाब में "मुक्केबाजी" से संबंधित लोगों के लिए: कोई नहीं है। String.valueOf(Object)यहाँ प्रयोग किया जाता है, और intकभी भी कोई अनबॉक्सिंग नहीं किया जाता है।

चाहे आप उपयोग करें Integer.toString()या इस String.valueOf(Object)बात पर निर्भर करें कि आप संभावित नल को कैसे संभालना चाहते हैं। क्या आप एक अपवाद (शायद) फेंकना चाहते हैं, या आपकी सूची (शायद) में "अशक्त" हैं। यदि पूर्व, क्या आप NullPointerExceptionया कुछ अन्य प्रकार फेंकना चाहते हैं ?

इसके अलावा, jsight की प्रतिक्रिया में एक छोटा दोष: Listएक इंटरफ़ेस है, आप उस पर नए ऑपरेटर का उपयोग नहीं कर सकते। मैं शायद java.util.ArrayListइस मामले में एक का उपयोग करूंगा , खासकर जब से हम सामने जानते हैं कि सूची कितनी लंबी होने की संभावना है।



2

@ जोनाथन: मुझसे गलती हो सकती है, लेकिन मेरा मानना ​​है कि String.valueOf () इस मामले में String.valueOf (int) से बॉक्सिंग करने के बजाय String.valueOf (ऑब्जेक्ट) फ़ंक्शन को कॉल करेगा। String.valueOf (ऑब्जेक्ट) सिर्फ "अशक्त" देता है यदि यह शून्य है या ऑब्जेक्ट को कॉल करता है। यदि स्ट्रिंग () गैर-अशक्त है, जिसमें बॉक्सिंग शामिल नहीं होना चाहिए (हालांकि स्पष्ट रूप से नई स्ट्रिंग ऑब्जेक्ट्स को शामिल करना शामिल है)।


2

मुझे लगता है कि डिबगिंग के अलावा किसी भी उद्देश्य के लिए Object.toString () का उपयोग करना वास्तव में एक बुरा विचार है, भले ही इस मामले में दोनों कार्यात्मक रूप से समतुल्य हैं (यह मानते हुए कि सूची में कोई अशक्त नहीं है)। डेवलपर्स बिना किसी चेतावनी के किसी भी स्ट्रींग () पद्धति के व्यवहार को बदलने के लिए स्वतंत्र हैं, जिसमें मानक पुस्तकालय में किसी भी वर्ग के स्ट्रींग () तरीके शामिल हैं।

बॉक्सिंग / अनबॉक्सिंग प्रक्रिया के कारण होने वाली प्रदर्शन समस्याओं के बारे में भी चिंता न करें। यदि प्रदर्शन महत्वपूर्ण है, तो बस एक सरणी का उपयोग करें। यदि यह वास्तव में महत्वपूर्ण है, तो जावा का उपयोग न करें। जेवीएम को आउटसोर्स करने की कोशिश से केवल दिल का दर्द होगा।


2

केवल विशेषज्ञों के लिए एक उत्तर:

    List<Integer> ints = ...;
    String all = new ArrayList<Integer>(ints).toString();
    String[] split = all.substring(1, all.length()-1).split(", ");
    List<String> strs = Arrays.asList(split);

यह काम करता है लेकिन अक्षमता की कीमत पर। जावा स्ट्रिंग्स प्रति चार बाइट्स हैं, इसलिए "," पूर्णांक को गिनने से पहले पूर्णांक प्रति चार बाइट निश्चित लागत जोड़ता है .... अन्य बातों के अलावा।
रॉबर्ट क्रिश्चियन

मुझे लगता है कि कच्चे सीपीयू चक्र दक्षता के संदर्भ में रेगेक्स अधिक समस्या हो सकती है। स्मृति के संदर्भ में, मुझे लगता है कि एक उचित कार्यान्वयन ("सूर्य" अनुचित कार्यान्वयन मानकर String) उसी बैकिंग सरणी (से all) को साझा करेगा , इसलिए वास्तव में वास्तव में काफी मेमोरी कुशल होगा, जो दीर्घकालिक प्रदर्शन के लिए महत्वपूर्ण होगा। जब तक आप केवल पाठ्यक्रम के तत्वों में से एक को रखना चाहते हैं ...
टॉम हैटिन -

2

लैंबडाज एक बहुत ही सरल और पठनीय तरीके से करने की अनुमति देता है। उदाहरण के लिए, मान लें कि आपके पास इंटेगर की एक सूची है और आप उन्हें उसी स्ट्रिंग प्रतिनिधित्व में परिवर्तित करना चाहते हैं जो आप कुछ ऐसा लिख ​​सकते हैं;

List<Integer> ints = asList(1, 2, 3, 4);
Iterator<String> stringIterator = convertIterator(ints, new Converter<Integer, String> {
    public String convert(Integer i) { return Integer.toString(i); }
}

जब आप परिणाम पर पुनरावृत्ति कर रहे हों, तो Lambdaj केवल रूपांतरण फ़ंक्शन लागू करता है।


1

आप "बॉक्सिंग ओवरहेड" से बच नहीं सकते हैं; जावा के अशुद्ध जेनेरिक कंटेनर केवल वस्तुओं को स्टोर कर सकते हैं, इसलिए आपके किलों को इंटेगर में बॉक्स किया जाना चाहिए। सिद्धांत रूप में, यह ऑब्जेक्ट को इंटेगर से डाउनकास्ट करने से बच सकता है (क्योंकि यह व्यर्थ है, क्योंकि ऑब्जेक्ट String.valueOf और Object.toString दोनों के लिए काफी अच्छा है) लेकिन मुझे नहीं पता कि कंपाइलर ऐसा करने के लिए पर्याप्त स्मार्ट है या नहीं। स्ट्रिंग से ऑब्जेक्ट में रूपांतरण कम-से-कम होना चाहिए, इसलिए मुझे उस बारे में चिंता करने के लिए विच्छेदित किया जाएगा।


संकलक ऐसा करने के लिए पर्याप्त स्मार्ट नहीं है। जब javac चलता है, तो यह वास्तव में सभी जेनरिक प्रकार की जानकारी को स्ट्रिप करता है। जेनेरिक संग्रह ALWAYS का अंतर्निहित कार्यान्वयन ऑब्जेक्ट संदर्भों को संग्रहीत करता है। आप वास्तव में <T> पैराट्राइजेशन को छोड़ सकते हैं और एक "कच्चा" प्रकार प्राप्त कर सकते हैं। "सूची l = नई सूची ()" बनाम "सूची <स्ट्रिंग> एल = नई सूची <स्ट्रिंग> ()"। बेशक, इसका मतलब है कि "सूची <स्ट्रिंग> l = (सूची <स्ट्रिंग>) नई सूची <Integer> ()" वास्तव में संकलन और चलाएगा, लेकिन जाहिर है, बहुत खतरनाक है।
डेव डॉपसन

1

मुझे ऐसा कोई समाधान नहीं दिखाई दिया, जो अंतरिक्ष जटिलता के प्रमुख का अनुसरण कर रहा हो। यदि पूर्णांकों की सूची में बड़ी संख्या में तत्व हैं तो यह बड़ी समस्या है।

It will be really good to remove the integer from the List<Integer> and free
the space, once it's added to List<String>.

हम इसे प्राप्त करने के लिए पुनरावृत्ति का उपयोग कर सकते हैं।

    List<Integer> oldList = new ArrayList<>();
    oldList.add(12);
    oldList.add(14);
    .......
    .......

    List<String> newList = new ArrayList<String>(oldList.size());
    Iterator<Integer> itr = oldList.iterator();
    while(itr.hasNext()){
        newList.add(itr.next().toString());
        itr.remove();
    }

1

धाराओं का उपयोग करना: यदि मान लें कि परिणाम पूर्णांक ( List<Integer> result) की सूची है :

List<String> ids = (List<String>) result.stream().map(intNumber -> Integer.toString(intNumber)).collect(Collectors.toList());

इसे हल करने के तरीकों में से एक। उम्मीद है की यह मदद करेगा।


1

मूल सूची में forEach पद्धति का उपयोग करके थोड़ा अधिक संक्षिप्त समाधान:

    List<Integer> oldList = Arrays.asList(1, 2, 3, 4, 5);
    List<String> newList = new ArrayList<>(oldList.size());
    oldList.forEach(e -> newList.add(String.valueOf(e)));

0

बस मज़े के लिए, jsr166y फोर्क-जॉइनिंग फ्रेमवर्क का उपयोग करके एक समाधान जो कि JDK7 में होना चाहिए।

import java.util.concurrent.forkjoin.*;

private final ForkJoinExecutor executor = new ForkJoinPool();
...
List<Integer> ints = ...;
List<String> strs =
    ParallelArray.create(ints.size(), Integer.class, executor)
    .withMapping(new Ops.Op<Integer,String>() { public String op(Integer i) {
        return String.valueOf(i);
    }})
    .all()
    .asList();

(अस्वीकरण: संकलित नहीं। कल्पना अंतिम नहीं है। आदि)

JDK7 में होने के लिए अनिश्चित रूप से एक प्रकार का अनुमान है और यह बनाने के लिए सिंथेटिक चीनी है कि withMapping कॉल कम क्रिया है:

    .withMapping(#(Integer i) String.valueOf(i))

0

यह एक ऐसी बुनियादी चीज है जिसे मैं बाहरी लाइब्रेरी का उपयोग नहीं करूंगा (यह आपके प्रोजेक्ट में एक निर्भरता का कारण बनेगा, जिसकी आपको आवश्यकता नहीं है)।

हमारे पास स्थैतिक विधियों का एक वर्ग है जिसे विशेष रूप से इस प्रकार की नौकरियों के लिए तैयार किया गया है। क्योंकि इसके लिए कोड इतना सरल है कि हम हॉटस्पॉट को हमारे लिए अनुकूलन करने दें। यह हाल ही में मेरे कोड में एक विषय लगता है: बहुत सरल (सीधा) कोड लिखें और हॉटस्पॉट को अपना जादू करने दें। हमारे पास कोड के आसपास प्रदर्शन संबंधी समस्याएं बहुत कम हैं - जब एक नया वीएम संस्करण आपके साथ आता है तो आपको सभी अतिरिक्त गति लाभ मिलते हैं आदि।

जितना मुझे जकार्ता कलेक्शन पसंद है, वे जेनरिक का समर्थन नहीं करते हैं और एलसीडी के रूप में 1.4 का उपयोग करते हैं। मैं Google संग्रह से सावधान हूं क्योंकि उन्हें अल्फा समर्थन स्तर के रूप में सूचीबद्ध किया गया है!


-1

मैं सिर्फ समस्या के लिए एक वस्तु उन्मुख समाधान के साथ झंकार करना चाहता था।

यदि आप डोमेन ऑब्जेक्ट को मॉडल करते हैं, तो समाधान डोमेन ऑब्जेक्ट्स में है। यहाँ डोमेन पूर्णांकों की एक सूची है, जिसके लिए हम स्ट्रिंग मान चाहते हैं।

सबसे आसान तरीका यह होगा कि आप सूची को परिवर्तित न करें।

कहा जा रहा है, बिना रूपांतरित होने के लिए, इंटेगर की मूल सूची को मूल्य की सूची में बदल दें, जहां मूल्य कुछ इस तरह दिखता है ...

class Value {
    Integer value;
    public Integer getInt()
    {
       return value;
    }
    public String getString()
    {
       return String.valueOf(value);
    }
}

यह तेज़ होगा और सूची की प्रतिलिपि बनाने की तुलना में कम मेमोरी लेगा।

शुभ लाभ!

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