2011-01-26 9 views
7

मान लीजिए मैं एक वस्तु है कि लग रहा है जैसे:कैसे गुण ArrayList से वस्तुओं की सूची प्राप्त करने के लिए

public class Obj { 
String foo; 
String bar; 
} 

अगर मैं प्रकार Obj की एक ArrayList बना सकते हैं और पॉप्युलेट, वहाँ एक तरह से मैं की एक सूची लौट सकते है सरणी सूची से सरणी के foo विशेषता में सभी वस्तुओं?

संपादित करें: मैं और अधिक स्पष्ट किया जाना चाहिए था, मुझे नहीं सूची के माध्यम से के माध्यम से यात्रा

+0

आप सूची objs है और वह सूची कि foo विशेषता है से एक दूसरे सूची बनाना चाहते हैं objs से सभी Obj के? – Ralph

उत्तर

7

आप अपने List<Obj> के माध्यम से पुनरावृति और एक नया List

उदा में foo प्रविष्टियों मुक़ाबला करना होगा

List<String> foos = new ArrayList<String>(); 
for (Obj obj : objs) { 
    foos.add(obj.foo) 
} 

या जावा 8 के लिए और परे, उपयोग इस प्रकार धाराओं:

objs.stream().map(o -> o.foo).collect(toList()); 
+3

मेरा पहला संस्करण यह होना था: 'var foos = objs.Select (x => x.foo);' जब तक मुझे एहसास हुआ कि यह एक जावा प्रश्न था। अरे तुम 'LINQ' भलाई! –

+0

आप गुवा जैसे कुछ का उपयोग करके सादे जावा में 'मानचित्र' के बराबर कर सकते हैं। स्पष्ट रूप से शामिल कुछ और काम शामिल हैं, लेकिन मूल सूची में सभी 'foo' मानों की एक प्रति के लिए स्मृति आवंटित करने के फायदे हैं। – ColinD

+1

क्या जावा 8 लैम्ब्डा इसके लिए कोई नई चतुरता प्रदान करता है? आला स्कैला-LINQ चालबाजी। – ken

0

दोहराएं ऐसा करने के लिए और सभी foo संपत्तियों की एक सेट बनाने के लिए करना चाहता था।

0

कुछ इस तरह?

List<String> foos = new ArrayList<String>(); 
for (Obj obj : objList) 
{ 
    foos.addElement(obj.foo); 
} 
4

Guava का उपयोग करके आप Lists.transform इस तरह का उपयोग कर List में वस्तुओं की foo संपत्ति के एक दृश्य बना सकते हैं:

public class Obj { 
    String foo; 
    String bar; 

    public static final Function<Obj, String> FOO = new Function<Obj, String>() { 
    public String apply(Obj input) { 
     return input.foo; 
    } 
    }; 
} 

public void someMethod(List<Obj> objs) { 
    List<String> foos = Lists.transform(objs, Obj.FOO); 
    ... 
} 

अन्य समाधान के विपरीत, यह विशुद्ध रूप से एक List<Obj> की दृश्य है और इस तरह यह पूरी तरह से अलग ArrayList या स्मृति में कुछ आवंटित नहीं करता है और आपके List<Obj> के आकार के बावजूद लगभग किसी भी समय बनाया जा सकता है। इसके अतिरिक्त, यदि आप मूल List<Obj> बदलते हैं, तो foos सूची उस परिवर्तन को प्रतिबिंबित करेगी।

जावा 8 में (2012 में कुछ समय के कारण), यह लैम्ब्डा अभिव्यक्तियों और विधि संदर्भों के साथ बहुत आसान हो जाएगा। आप इस तरह कुछ करने के लिए सक्षम हो जाएगा:

List<Obj> objs = ... 
List<String> foos = objs.map(#Obj.getFoo); 
10

इस प्रयास करें:

Collection<String> names = CollectionUtils.collect(personList, TransformerUtils.invokerTransformer("getName")); 

उपयोग Apache Commons संग्रह API।

+0

धन्यवाद, यह विधि सरल और त्वरित है – Vito

1

@ सोरोडिप का उत्तर Apache Commons Collections पर आधारित एक कॉम्पैक्ट समाधान का उपयोग करता है। लेकिन उस समस्या का समाधान नहीं typesafe, के बाद से Transfomer संपत्ति का संदर्भ स्ट्रिंग अभिव्यक्ति के माध्यम से है: TransformerUtils.invokerTransformer("getName")

यहाँ एक अधिक वर्बोज़ है, लेकिन typesafe समाधान अपाचे कॉमन्स संग्रह का उपयोग कर:

Collection<String> values = CollectionUtils.collect(messages, new Transformer<Obj, String>(){ 

      @Override 
      public String transform(Obj input) { 
       return input.getFoo(); 
      } 

     }); 

ऊपर समाधान अपाचे कॉमन्स का उपयोग करता है संग्रह संस्करण> = 4, जो कि प्रकार की सुरक्षा के लिए जेनेरिक का समर्थन करता है।

नीचे अपाचे संग्रह के लिए कम typesafe संस्करण संस्करण < 4, जो जेनरिक का उपयोग नहीं करता है:

Collection values = CollectionUtils.collect(messages, new Transformer(){ 

      @Override 
      public Object transform(Object input) { 
       Obj obj = (Obj) input; 
       return obj.getFoo(); 
      } 

     }); 
संबंधित मुद्दे