2008-08-20 33 views
83

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

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

उत्तर

64

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

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

जब यह आसान है, इसे सौंदर्य कहा जाता है। – Elbek

+1

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

+0

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

2

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

9

स्ट्रिंग.वल्यू का उपयोग करने के बजाय मैं .toString() का उपयोग करता हूं; यह @ johnathan.holland

द्वारा वर्णित कुछ ऑटो मुक्केबाजी से बचाता है। जावाडोक कहता है कि valueOf Integer.toString() जैसी ही चीज़ देता है।

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

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

करेगा जैसा कि टॉम हौटिन ने 'जीतने' के जवाब में बताया है, कोई उदाहरण की सूची नहीं दे सकता क्योंकि यह केवल एक इंटरफ़ेस है। –

+0

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

2

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

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

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

है कि यह ज्यादा मायने रखती है, लेकिन मैं toString का प्रयोग करेंगे:

+0

+1 "दिल दर्द" के लिए +1 ... – Smalltown2k

9

String.valueOf के लिए स्रोत यह दिखाता है।

1

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

+0

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

3

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

CollectionUtils

कुछ कलेक्ट तरीकों पर एक नजर है।

+4

अपाचे संग्रह का कभी भी उपयोग न करें। वे पुराने, पुराने, टाइप-सुरक्षित नहीं हैं, और खराब लिखे गए हैं। – KitsuneYMG

39

आप जो कर रहे हैं वह ठीक है, लेकिन यदि आपको 'जावा-अप-अप' की आवश्यकता महसूस होती है तो आप Transformer और collect methodApache Commons से उपयोग कर सकते हैं, उदा।:

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); 
+0

वाह, शांत सामान! – Verhogen

+1

CollectionUtils.collect (collectionOfIntegers, नई org.apache.commons.collections.functors.StringValueTransformer()); लेकिन, StringValueTransformer String.valueOf ... –

+5

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

3

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

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

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

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); 
+0

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

+0

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

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 संग्रह से सावधान हूं क्योंकि उन्हें अल्फा समर्थन स्तर के रूप में सूचीबद्ध किया गया है!

82

Google Collections from Guava-Project का उपयोग करके आप Lists कक्षा में 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()); 

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

ध्यान रखें कि Functions.toStringFunction() शून्य पर लागू होने पर NullPointerException फेंक देगा, इसलिए यदि आप सुनिश्चित हैं कि आपकी सूची में शून्य नहीं है तो केवल इसका उपयोग करें।

+1

रखना चाहते हैं यह अगर वहाँ Functions.toStringFunction बगल में अधिक तैयार कार्य हैं अच्छा हो जाएगा() – ThiamTeck

+1

स्वच्छ लेकिन शायद नहीं के रूप में तेजी से .. मूल्य प्रति 1 अतिरिक्त समारोह कॉल? – h3xStream

+3

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

2

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

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); } 
} 

लैम्बडाज केवल परिणाम समारोह पर लागू होता है जब आप परिणाम पर पुनरावृत्ति कर रहे होते हैं।

8

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

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

+1 शुद्ध hackishness खातिर। – metasim

-1

मैं बस समस्या के ऑब्जेक्ट उन्मुख समाधान के साथ झुकना चाहता था।

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

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

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

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

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

शुभकामनाएं!

52

जावा 8 के लिए समाधान 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()); 
+0

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

5

एक और समाधान अमरूद और जावा 8

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

का उपयोग कर मैं किसी भी समाधान जो अंतरिक्ष जटिलता के प्रिंसिपल पीछा कर रहा है नहीं देखा। यदि पूर्णांक की सूची में बड़ी संख्या में तत्व हैं तो यह बड़ी समस्या है।

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

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

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(); 
    } 
संबंधित मुद्दे