2012-02-23 19 views
6

का उपयोग करते समय मैं एक जटिल वस्तु क्रमानुसार करने की थी, लेकिन उसके घटक में से एक गैर serializable (एक तीसरी पार्टी ग्राफ वस्तु) था, इसलिए मैं इस ग्राफ़ वर्ग के एक कस्टम serializable संस्करण बनाया और गैर-धारावाहिक वस्तु को कस्टम ऑब्जेक्ट्स में कनवर्ट करने के लिए इस्तेमाल किया गया नक्शा सूची परिवर्तित। Serialization writeObject अभी भी असफल रहा। मुझे जानने में दिलचस्पी होगी क्यों? मेरी धारणा यह है कि Lists.transform अपने ऑपरेशन को आलसी प्रदर्शन करता है (मूल ऑब्जेक्ट के लिए एक छिपा संदर्भ धारण करता है।)जावा क्रमबद्धता समस्याएं, अमरूद Lists.transform

क्या इस समस्या के लिए कोई समाधान भी है?

उत्तर

11

Lists.transform() lazily प्रदर्शन के रूप में आप पर शक करता है। आप

ImmutableList.copyOf(Lists.transform(...)) 

Lists.newArrayList(Lists.transform(...)) 

में से एक कर सकता है या, आप एक अपरिवर्तनीय संस्करण चाहते हैं, और फिर जिसके परिणामस्वरूप सूची को क्रमानुसार।

+0

आप की जरूरत नहीं है नई सूची बनाने के लिए, @eneveu उत्तर देखें। – Xaerxess

+2

ओपी ने कहा कि सूची से विशेष रूप से गैर-धारावाहिक तत्वों से भरा था। –

+1

@Xenerness क्या आप अपनी टिप्पणी संशोधित कर सकते हैं? आप enum trick (@eneveu answer) का उपयोग करके केवल एक धारावाहिक सूची नहीं प्राप्त कर सकते हैं। यह उत्तर प्रश्न के बारे में सबसे उपयोगी है। –

1

यदि आपने सूची # परिवर्तन से लौटाई गई सूची को क्रमबद्ध करने का प्रयास किया है, तो इंटरफ़ेस सूची स्वयं Serializable नहीं है।

+1

यह समस्या क्यों होगी? यह कार्यान्वयन है जिसे धारावाहिकरण के दौरान माना जाता है। और कार्यान्वयन Lists.transform() द्वारा दिया Serializable को लागू करता है: "। लौटे सूची हमेशा Serializable लागू करता है, लेकिन क्रमबद्धता केवल सफल होगा जब fromList और समारोह serializable रहे हैं" (से [जावाडोक] (http://docs.guava-libraries.googlecode.com/git-history/v11.0.1/javadoc/com/google/common/collect/Lists.html)) –

6

Lists.transform() मूल सूची की एक तब्दील देखने देता है। Lists.transform() javadoc से:

लौटे सूची हमेशा Serializable लागू करता है, लेकिन क्रमबद्धता केवल सफल होने जब fromList और समारोह serializable हैं जाएगा।

जब परिवर्तित दृश्य को क्रमबद्ध करते हैं, तो आप वास्तव में मूल सूची, साथ ही फ़ंक्शन को क्रमबद्ध कर रहे हैं। आपके मामले में, यह विफल हो जाता है क्योंकि आपकी मूल सूची धारावाहिक नहीं है (क्योंकि इसमें गैर-क्रमिक ग्राफ तत्व शामिल हैं)। लेकिन यह भी असफल हो सकता है क्योंकि फ़ंक्शन serializable लागू नहीं करता है।

BTW, वहाँ शब्दाडंबर बिना serializable कार्यों बनाने के लिए एक छोटे से चाल है। इसके बजाय ऐसा करने का:

private static final class MyFunction extends Function<String, String> implements Serializable { 
    private static final MyFunction INSTANCE = new MyFunction(); 

    @Override 
    public String apply(String input) { 
     return "[" + input + "]"; 
    } 

    private Object readResolve() { 
     return INSTANCE; 
    } 
    private static final long serialVersionUID = 1; 
    } 

आप enum सिंगलटन पैटर्न है, जो बहुत कम अत्यधिक शब्द है, और के लिए मुक्त आप क्रमबद्धता हो जाता है (क्योंकि enums serializable कर रहे हैं) का उपयोग कर सकते हैं। यह भी सुनिश्चित करता है कि आपका फ़ंक्शन एक सिंगलटन है:

// enum singleton pattern 
    private enum MyFunction implements Function<String, String> { 
    INSTANCE; 

    @Override 
    public String apply(String input) { 
     return "[" + input + "]"; 
    } 
    } 
+2

बहुत बढ़िया ... प्रभावी जावा। धन्यवाद। –

+1

हाँ, जोशुआ ब्लोच प्रभावी जावा में बताता है कि यह सिंगलटन बनाने का सबसे अच्छा तरीका है। एक enum serializable है, यह विभिन्न de-serialization हमलों के लिए कमजोर नहीं है, और JVM इसकी एकता की गारंटी देता है। आप गुवा पुस्तकालय में पैटर्न के अच्छे उदाहरण पा सकते हैं: http://code.google।कॉम/पी/अमरूद-पुस्तकालय/स्रोत/ब्राउज़/अमरूद/src/com/google/common/base/Functions.java # 59 –

+0

ईजे का हवाला देते हुए और गुवा में अच्छे पैटर्न के अनुप्रयोगों के लिए बोनस अंक, भले ही उत्तर ' टी उपयोगी है क्योंकि 'सेलिस्ट' धारावाहिक नहीं होने वाला है। –

संबंधित मुद्दे