C # ตั้งคอลเลกชัน?


488

ไม่มีใครรู้ว่ามีเทียบเท่ากับSetคอลเลกชันของ Java ใน C # หรือไม่? ฉันรู้ว่าคุณสามารถเลียนแบบชุดโดยใช้DictionaryหรือHashTableโดยการเติม แต่ไม่สนใจค่า แต่นั่นไม่ใช่วิธีที่สวยงามมาก

คำตอบ:


142

ลองHashSet :

คลาส HashSet (Of T) จัดเตรียมชุดการดำเนินการที่มีประสิทธิภาพสูง ชุดคือชุดที่ไม่มีองค์ประกอบที่ซ้ำกันและองค์ประกอบที่ไม่มีลำดับ ...

ความจุของวัตถุ HashSet (Of T) คือจำนวนองค์ประกอบที่วัตถุสามารถเก็บได้ ความจุของวัตถุ HashSet (Of T) จะเพิ่มขึ้นโดยอัตโนมัติเมื่อมีการเพิ่มองค์ประกอบเข้ากับวัตถุ

คลาส HashSet (Of T) ขึ้นอยู่กับรุ่นของชุดทางคณิตศาสตร์และให้การดำเนินการชุดที่มีประสิทธิภาพสูงคล้ายกับการเข้าถึงคีย์ของคอลเลกชันDictionary (ของ TKey, TValue)หรือHashtable กล่าวง่ายๆว่าคลาส HashSet (Of T) สามารถคิดว่าเป็นคอลเลกชันพจนานุกรม (ของ TKey, TValue)โดยไม่มีค่า

ไม่มีการเรียงลำดับคอลเลกชัน HashSet (Of T) และไม่สามารถมีองค์ประกอบที่ซ้ำกัน ...


8
น่าเสียดายที่ HashSets ไม่ได้ถูกเพิ่มจนกระทั่งเมื่อไม่นานมานี้ หากคุณกำลังทำงานในเฟรมเวิร์กเวอร์ชันที่เก่ากว่าคุณจะต้องยึดพจนานุกรม <> หรือ Hashtable ของคุณ
Greg D

413

หากคุณกำลังใช้ NET 3.5 HashSet<T>คุณสามารถใช้ เป็นความจริงที่ .NET ไม่รองรับชุดและ Java ทำ

PowerCollections Wintellectอาจช่วยเกินไป


16
ฉันสงสัยว่า Set เป็นคำหลักในบางภาษาซึ่งอาจทำให้เกิดปัญหา
Jon Skeet

3
@Manish: ไม่เลย ดูหัวข้อ 2.4.3 ของข้อกำหนด C # 3 มันมีความหมายพิเศษสำหรับคุณสมบัติเท่านั้น
Jon Skeet

28
เหตุผลที่เรียกมันว่า HashSet แทนที่จะเป็นเพียงแค่เซ็ตเหมือนกับใน Java- "Set" อธิบายถึงอินเตอร์เฟสในขณะที่ "HashSet" อธิบายถึงการใช้งานโดยเฉพาะนี่คือ Set ที่สนับสนุนโดย Hash Map ด้วยวิธีนี้เรารู้ (หรือควรคาดหวังอย่างยิ่ง) ว่าการแทรกและการเข้าถึงควรใช้เวลาเข้าถึง O (1) เทียบกับ "LinkedListSet" ซึ่งจะทำให้เราคาดว่าการแทรกและการเข้าถึงจะใช้เวลา O (n)
David Souther

5
คุณหมายถึงอะไร ".NET ไม่รองรับชุดและ Java ทำ" ชุดนี้ไม่สมบูรณ์เมื่อเทียบกับ Java หรือไม่
Louis Rhys

34
@Louis: คุณกำลังพูดถึงชุดอะไร? Java มีจำนวนมากของการใช้งานที่แตกต่างกันของชุดสำหรับสถานการณ์ต่างๆ .NET มีหนึ่งรายการใน. NET 3.5 (HashSet) และสองรายการใน. NET 4 (HashSet และ SortedSet) ความจริงที่ว่าเราต้องรอจนกระทั่ง. NET 3.5 เริ่มต้นด้วยค่อนข้างน่าแปลกใจ
Jon Skeet

26

หากคุณใช้. NET 4.0 หรือใหม่กว่า:

SortedSet<T>ในกรณีที่คุณจำเป็นต้องเรียงลำดับการใช้งานแล้ว มิฉะนั้นถ้าคุณทำไม่ได้แล้วใช้HashSet<T>ตั้งแต่มันO(1)สำหรับการค้นหาและจัดการการดำเนินงาน ในขณะที่SortedSet<T>เป็นO(log n)สำหรับการค้นหาและจัดการการดำเนินงาน



13

ฉันใช้เสื้อคลุมรอบ a Dictionary<T, object>, เก็บค่าว่างไว้ในค่า สิ่งนี้จะช่วยให้ O (1) เพิ่มค้นหาและลบคีย์และสำหรับทุกเจตนาและจุดประสงค์ทำหน้าที่เหมือนชุด


2
คุณต้องหมายความว่ามันเทียบเท่ากับ std :: unordered_set std :: set ได้รับคำสั่ง ตัวอย่างเช่นคุณสามารถค้นหาจุดเริ่มต้นและจุดสิ้นสุดของช่วงได้อย่างรวดเร็วและวนซ้ำตั้งแต่ต้นจนจบโดยไปที่รายการในการสั่งซื้อคีย์ SortedDictionary เป็นเทียบเท่าประมาณเพื่อมาตรฐาน :: ชุด
doug65536

11

ดูPowerCollectionsที่ CodePlex นอกเหนือจาก Set and OrderedSet แล้วยังมีประเภทคอลเลกชันที่มีประโยชน์อื่น ๆ อีกมากมายเช่น Deque, MultiDictionary, กระเป๋า, OrderedBag, OrderedDictionary และ OrderedMultiDictionary

สำหรับคอลเลกชันมากขึ้นนอกจากนี้ยังมีห้องสมุดเก็บ C5 ทั่วไป


-5

ฉันรู้ว่านี่เป็นเธรดเก่า แต่ฉันพบปัญหาเดียวกันและพบว่า HashSet ไม่น่าเชื่อถือมากเพราะได้รับเมล็ดเดียวกัน GetHashCode () ส่งคืนรหัสที่แตกต่างกัน ดังนั้นฉันคิดว่าทำไมไม่ใช้รายชื่อและซ่อนวิธีการเพิ่มเช่นนี้

public class UniqueList<T> : List<T>
{
    public new void Add(T obj)
    {
        if(!Contains(obj))
        {
            base.Add(obj);
        }
    }
}

เนื่องจากรายการใช้วิธี Equals เพียงอย่างเดียวในการกำหนดความเท่าเทียมกันคุณสามารถกำหนดวิธี Equals ในประเภท T ของคุณเพื่อให้แน่ใจว่าคุณได้รับผลลัพธ์ที่ต้องการ


13
เหตุผลที่คุณไม่ต้องการที่จะใช้นี้เป็นเพราะList.ContainsมีความO(n)ซับซ้อนซึ่งหมายความว่าคุณAddวิธีการตอนนี้กลายเป็นO(n)ความซับซ้อนเป็นอย่างดี การสมมติว่าคอลเล็กชันด้านในไม่จำเป็นต้องปรับขนาดAddทั้งสำหรับListและHashMapควรมีO(1)ความซับซ้อน TLDR: วิธีนี้ใช้ได้ แต่มันแฮ็กและมีประสิทธิภาพน้อยกว่า
Richard Marskell - Drackir

6
แน่นอนถ้าวัตถุของคุณไม่ส่งคืนค่าที่เหมาะสมสำหรับ GetHashCode คุณไม่ควรใส่วัตถุเหล่านั้นลงในคอนเทนเนอร์ที่ใช้แฮช การแก้ไข GetHashCode จะดีกว่าการใช้คอนเทนเนอร์ที่มีประสิทธิภาพน้อยกว่า
bmm6o
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.