2010-11-03 16 views
5

स्कैला संग्रह API में सेट्स और सूचियों के बीच स्थिरता की कमी क्यों है?स्कैला संग्रह असंगतता

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

val set = Set[A]() 
set += new A 

हालांकि, कोई म्यूटेबल सूची नहीं है, प्रति से। यदि मैं सूचियों का उपयोग कर एक समान कोड स्निपेट लिखना चाहता हूं, तो किस डेटा संरचना का उपयोग करना है? लिंक्डलिस्ट एक अच्छे उम्मीदवार के रूप में लगता है, क्योंकि यह उत्परिवर्तनीय है, लेकिन इसमें कोई + = विधि परिभाषित नहीं है। ListBuffer आवश्यकताओं को पूरा करने लगता है, लेकिन यह एक सूची नहीं है।

2.8 संग्रह डॉक्स पढ़ने के बाद मैं इस निष्कर्ष पर आ MutableList शायद सबसे अच्छा फिट है।

मैं अभी भी किसी भी तरह इच्छा scala.collection.mutable.List था।

+1

और mutable नहीं .MutableSet? :-) –

उत्तर

20

इस का कारण यह है कि जावा सह का विकल्प चुना है कार्यात्मकList प्रकार कुछ है कि ऐसा नहीं है मतलब है (अर्थात java.util.List एक सूची नहीं है) है।

यह संभवतः एक कार्यात्मक प्रोग्रामिंग भाषा के लिए परिवर्तनीयList होने का कोई अर्थ नहीं है क्योंकि इस प्रकार का एक ऑक्सीमोरोन है। इसलिए ListBuffer या ArrayBuffer। या बस IndexedSeq का उपयोग करें, जिनमें से उत्परिवर्तनीय और अपरिवर्तनीय कार्यान्वयन

3

ArraySeq क्या आप के लिए देख रहे हैं, सिवाय + = असाधारण धीमी है हो सकता है। आप java.util.ArrayList और आयात संग्रह का भी उपयोग कर सकते हैं। जावा कनवर्जन._

ऐसा लगता है कि स्कैला में निरंतर समय सूचकांक (जावा के लिए ऐरेलिस्ट जैसे) के साथ एक अच्छा उत्परिवर्तनीय सूची-जैसे संग्रह नहीं है।

किसी भी मामले में, ध्यान दें कि "सूची" वास्तव में प्रकार "scala.immutable.List" को दर्शाता है। इसलिए Seq (या कुछ और अधिक सार संग्रह प्रकार), वह प्रकार है जिसे आप "सूची" के बजाय विधियों में अपेक्षा कर सकते हैं यदि आप अपरिवर्तनीय/परिवर्तनीय संग्रहों को सामान्यीकृत करना चाहते हैं।

अधिक आदर्श एक IndexedSeq है, जो एक तरह से इसका मतलब है कि सूचकांक आपरेशन कि वसूली के लिए performant है की आवश्यकता वाले है। हालांकि, मुझे यकीन नहीं है कि ListBuffer उस श्रेणी में पड़ता है।

+0

ऐरेबफर के बारे में क्या? –

+3

स्कैला की "अच्छी म्यूटेबल सूची जैसी संग्रह" "जैसे जावा के लिए ऐरेलिस्ट" अर्रेबफर है। –

+0

ऐरेबफर संलग्न करने के लिए बहुत अच्छा है लेकिन प्रीपेन्ड के लिए उतना अच्छा नहीं है। जावा की ऐरेलिस्ट वास्तव में लागत को बढ़ाने के लिए लागत को कम करने की कोशिश करेगी, जिससे मेरी राय में थोड़ा बेहतर हो जाएगा। हां ArrayBuffer शायद पर्याप्त है यदि आप केवल एक सूची और अनुक्रमण तत्वों में शामिल हैं। – jsuereth

2

क्योंकि Set केवल एक विशेषता है - यह सार है और कार्यान्वयन की आवश्यकता है। तो कोई कक्षाओं के बारे में बात कर सकता है जो mutable.Set या immutable.Set हैं।

इस बीच, List एक वर्ग है, (सार) गुण immutable.LinearSeq का कार्यान्वयन है। कोई अन्य वर्ग कभी भी नहीं हो सकता है जो List भी है। हालांकि, आप पाएंगे कि mutable.LinearSeq विशेषता है।

जावा शब्दों में, आप कक्षाओं के साथ इंटरफेस की तुलना कर रहे हैं - वे अलग हैं।

+0

संप्रदाय में भेद। 16.8 सीढ़ियों की किताब, वैश्विक सूची वस्तु (सभी सूची वस्तुओं पर विधियां काम नहीं करती हैं) बनाम सूची वर्ग, उल्लेखनीय है। –

9

स्कैला के संग्रह पुस्तकालयों में Set का अनुक्रम/सूची एनालॉग Seq है। ListSeq का एक विशेष, अपरिवर्तनीय कार्यान्वयन है, जैसा कि Vector है। ArrayBuffer या ListBuffermutable.Seq के सामान्य कार्यान्वयन हैं।

+0

सरल स्पष्टीकरण के लिए धन्यवाद - यह हमेशा मुझे परेशान करता है। –

0

scala.collection.mutable.{LinkedList,DoubleLinkedList} मत भूलना। वे उत्परिवर्तनीय हैं, और वे LinearSeq हैं। उत्परिवर्तन थोड़ा अजीब है - आप elem संदर्भ, और next संदर्भ को निर्दिष्ट करके पूंछ को निर्दिष्ट करके सिर को संशोधित कर सकते हैं।

उदाहरण के लिए, यह पाश सभी नकारात्मक मानों को शून्य में बदल देता है।

val lst = collection.mutable.LinkedList(1, -2, 7, -9) 
var cur = lst 
while (cur != Nil) { 
    if (cur.elem < 0) cur.elem = 0 
    cur = cur.next 
} 

यह पाश सूची से हर दूसरे तत्व को हटा देता है।

var cur = lst 
while (cur != Nil && cur.next != Nil) { 
    cur.next = cur.next.next 
    cur = cur.next 
} 

मैं यह सुझाव नहीं दे रहा हूं कि ये अपरिवर्तनीय सूची से बेहतर हैं। मैं बस यह इंगित कर रहा हूं कि स्कैला में परिवर्तनीय सूचियां हैं जो आपके डेटा संरचना वर्ग में जो कुछ आपने देखी हैं, उससे काफी समान दिखती हैं।

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