C#のLinkedHashSet(Java)に相当するものは何ですか?C#でLinkedHashSet(Java)に相当するものは何ですか?
答えて
私は未完成の方法を完了し、一般的に 'achitaka-san'が投稿したクラスを研磨しました。
public class LinkedHashSet<T> : ISet<T> {
private readonly IDictionary<T, LinkedListNode<T>> dict;
private readonly LinkedList<T> list;
public LinkedHashSet(int initialCapacity) {
this.dict = new Dictionary<T,LinkedListNode<T>>(initialCapacity);
this.list = new LinkedList<T>();
}
public LinkedHashSet() {
this.dict = new Dictionary<T,LinkedListNode<T>>();
this.list = new LinkedList<T>();
}
public LinkedHashSet(IEnumerable<T> e) : this() {
addEnumerable(e);
}
public LinkedHashSet(int initialCapacity, IEnumerable<T> e) : this(initialCapacity) {
addEnumerable(e);
}
private void addEnumerable(IEnumerable<T> e) {
foreach (T t in e) {
Add(t);
}
}
//
// ISet implementation
//
public bool Add(T item) {
if (this.dict.ContainsKey(item)) {
return false;
}
LinkedListNode<T> node = this.list.AddLast(item);
this.dict[item] = node;
return true;
}
public void ExceptWith(IEnumerable<T> other) {
if (other == null) {
throw new ArgumentNullException("other cannot be null");
}
foreach (T t in other) {
Remove(t);
}
}
public void IntersectWith(IEnumerable<T> other) {
if (other == null) {
throw new ArgumentNullException("other cannot be null");
}
T[] ts = new T[Count];
CopyTo(ts, 0);
foreach (T t in ts) {
if (!System.Linq.Enumerable.Contains(other, t)) {
Remove(t);
}
}
}
public bool IsProperSubsetOf(IEnumerable<T> other) {
if (other == null) {
throw new ArgumentNullException("other cannot be null");
}
int contains = 0;
int noContains = 0;
foreach (T t in other) {
if (Contains(t)) {
contains++;
} else {
noContains++;
}
}
return contains == Count && noContains > 0;
}
public bool IsProperSupersetOf(IEnumerable<T> other) {
if (other == null) {
throw new ArgumentNullException("other cannot be null");
}
int otherCount = System.Linq.Enumerable.Count(other);
if (Count <= otherCount) {
return false;
}
int contains = 0;
int noContains = 0;
foreach (T t in this) {
if (System.Linq.Enumerable.Contains(other, t)) {
contains++;
} else {
noContains++;
}
}
return contains == otherCount && noContains > 0;
}
public bool IsSubsetOf(IEnumerable<T> other) {
if (other == null) {
throw new ArgumentNullException("other cannot be null");
}
foreach (T t in this) {
if (!System.Linq.Enumerable.Contains(other, t)) {
return false;
}
}
return true;
}
public bool IsSupersetOf(IEnumerable<T> other) {
if (other == null) {
throw new ArgumentNullException("other cannot be null");
}
foreach (T t in other) {
if (!Contains(t)) {
return false;
}
}
return true;
}
public bool Overlaps(IEnumerable<T> other) {
if (other == null) {
throw new ArgumentNullException("other cannot be null");
}
foreach (T t in other) {
if (Contains(t)) {
return true;
}
}
return false;
}
public bool SetEquals(IEnumerable<T> other) {
if (other == null) {
throw new ArgumentNullException("other cannot be null");
}
int otherCount = System.Linq.Enumerable.Count(other);
if (Count != otherCount) {
return false;
}
return IsSupersetOf(other);
}
public void SymmetricExceptWith(IEnumerable<T> other) {
if (other == null) {
throw new ArgumentNullException("other cannot be null");
}
T[] ts = new T[Count];
CopyTo(ts, 0);
HashSet<T> otherList = new HashSet<T>(other);
foreach (T t in ts) {
if (otherList.Contains(t)) {
Remove(t);
otherList.Remove(t);
}
}
foreach (T t in otherList) {
Add(t);
}
}
public void UnionWith(IEnumerable<T> other) {
if (other == null) {
throw new ArgumentNullException("other cannot be null");
}
foreach (T t in other) {
Add(t);
}
}
//
// ICollection<T> implementation
//
public int Count {
get {
return this.dict.Count;
}
}
public bool IsReadOnly {
get {
return this.dict.IsReadOnly;
}
}
void ICollection<T>.Add(T item) {
Add(item);
}
public void Clear() {
this.dict.Clear();
this.list.Clear();
}
public bool Contains(T item) {
return this.dict.ContainsKey(item);
}
public void CopyTo(T[] array, int arrayIndex) {
this.list.CopyTo(array, arrayIndex);
}
public bool Remove(T item) {
LinkedListNode<T> node;
if (!this.dict.TryGetValue(item, out node)) {
return false;
}
this.dict.Remove(item);
this.list.Remove(node);
return true;
}
//
// IEnumerable<T> implementation
//
public IEnumerator<T> GetEnumerator() {
return this.list.GetEnumerator();
}
//
// IEnumerable implementation
//
IEnumerator IEnumerable.GetEnumerator() {
return this.list.GetEnumerator();
}
}
必要usings:
using System;
using System.Collections;
using System.Collections.Generic;
警告:このクラスは、特にISET法大部分は未テストです。自己責任。
誰かがこの点を知りたがっていれば幸いです。 :)
C#では直接的な機能はありません。使用する適切なクラスは、望ましい動作に依存します。 HashSet
クラスは、要素の一意性を保持します。また、SortedSet
とSortedDictionary
をチェックすることもできます。
リンクされたリストとセットデータ構造に必要な一意性を組み合わせたクラスはありません。したがって、両方の動作が必要な場合は、自分でビルドする必要があります。
私は簡単にHashSet
を実装しており、挿入の順序を保証しています。項目を検索するにはDictionary
、注文を保存するにはLinkedList
を使用します。 3つの挿入、削除、検索はすべてO(1)のままです。
public class OrderedSet<T> : ISet<T>
{
private readonly IDictionary<T, LinkedListNode<T>> m_Dictionary;
private readonly LinkedList<T> m_LinkedList;
public OrderedSet()
{
m_Dictionary = new Dictionary<T, LinkedListNode<T>>();
m_LinkedList = new LinkedList<T>();
}
public bool Add(T item)
{
if (m_Dictionary.ContainsKey(item)) return false;
var node = m_LinkedList.AddLast(item);
m_Dictionary.Add(item, node);
return true;
}
void ICollection<T>.Add(T item)
{
Add(item);
}
public void Clear()
{
m_LinkedList.Clear();
m_Dictionary.Clear();
}
public bool Remove(T item)
{
LinkedListNode<T> node;
bool found = m_Dictionary.TryGetValue(item, out node);
if (!found) return false;
m_Dictionary.Remove(item);
m_LinkedList.Remove(node);
return true;
}
public int Count
{
get { return m_Dictionary.Count; }
}
public IEnumerator<T> GetEnumerator()
{
return m_LinkedList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public bool Contains(T item)
{
return m_Dictionary.ContainsKey(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
m_LinkedList.CopyTo(array, arrayIndex);
}
public virtual bool IsReadOnly
{
get { return m_Dictionary.IsReadOnly; }
}
public void UnionWith(IEnumerable<T> other)
{
throw GetNotSupportedDueToSimplification();
}
public void IntersectWith(IEnumerable<T> other)
{
throw GetNotSupportedDueToSimplification();
}
public void ExceptWith(IEnumerable<T> other)
{
throw GetNotSupportedDueToSimplification();
}
public bool IsSubsetOf(IEnumerable<T> other)
{
throw GetNotSupportedDueToSimplification();
}
public void SymmetricExceptWith(IEnumerable<T> other)
{
throw GetNotSupportedDueToSimplification();
}
public bool IsSupersetOf(IEnumerable<T> other)
{
throw GetNotSupportedDueToSimplification();
}
public bool IsProperSupersetOf(IEnumerable<T> other)
{
throw GetNotSupportedDueToSimplification();
}
public bool IsProperSubsetOf(IEnumerable<T> other)
{
throw GetNotSupportedDueToSimplification();
}
public bool Overlaps(IEnumerable<T> other)
{
throw GetNotSupportedDueToSimplification();
}
public bool SetEquals(IEnumerable<T> other)
{
throw GetNotSupportedDueToSimplification();
}
private static Exception GetNotSupportedDueToSimplification()
{
return new NotSupportedException("This method is not supported due to simplification of example code.");
}
}
JavaのLinkedHashSetと事実上同等であるため、HashSetはジョブを実行します。 HashSetはリンクされたリストによってサポートされていますが、ドキュメントには順序が保持されていること、または配列ベースのリンクされたリストによって保持されていることが明示されていません。 the source codeから、実装がLinkedHashSetであることがわかります。
Java LinkedHashSetと同じように重複は許可されません。これとLinkedHashSetの違いの1つは、セットから何かを削除すると、配列内の要素を空きとしてマークするだけなので、remove()の後に項目を追加すると空の配列スロットが最初に「追加」されます。これを回避する方法は、TrimExcess()メソッドを呼び出すことです。したがって、多くのユースケースでは全く同じではありませんが、シリアライズしてデシリアライズし、効果的に変更不可能なセットを作成した場合はうまく動作します。
常にremove()をサブクラス化してオーバーライドして、常に同じ動作を得るためにTrimExcess()を呼び出すことができます。また、LinkedHashSetクラスの名前を明確にすることができます!
using System;
using System.Collections.Generic;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
String[] crew = {"Spock", "Kirk", "Bones", "Picard", "Uhura", "Chekov"};
HashSet<String> linkedHashSet = new HashSet<String>(crew);
// Show order is preserved
foreach(String value in linkedHashSet){
Console.Write(value); Console.Write(" ");
}
// Remove from the middle
linkedHashSet.Remove("Picard");
Console.WriteLine();
foreach(String value in linkedHashSet){
Console.Write(value); Console.Write(" ");
}
// Add it back but it is back in the middle not the end
linkedHashSet.Add("Picard");
Console.WriteLine();
foreach(String value in linkedHashSet){
Console.Write(value); Console.Write(" ");
}
// Remove and trim then add
linkedHashSet.Remove("Picard");
linkedHashSet.TrimExcess();
linkedHashSet.Add("Picard");
Console.WriteLine();
foreach(String value in linkedHashSet){
Console.Write(value); Console.Write(" ");
}
Console.WriteLine();
}
}
}
出力:
Spock Kirk Bones Picard Uhura Chekov
Spock Kirk Bones Uhura Chekov
Spock Kirk Bones Picard Uhura Chekov
Spock Kirk Bones Uhura Chekov Picard
- 1. C#でのJavaのデフォルト(パッケージ)アクセスに相当するものは何ですか?
- 2. C#でJavaのSimpleDateFormatクラスに相当するものは何ですか?
- 3. curlコマンドのjavaに相当するものは何ですか?
- 4. Debugger.Launch()のJavaに相当するものは何ですか?
- 5. Java Stream.collectのKotlinに相当するものは何ですか?
- 6. java androidのNSOperationQueueに相当するものは何ですか?
- 7. Regexp :: AssembleのJavaに相当するものは何ですか?
- 8. Java 8のjava.util.function.Consumer <>のC#に相当するものは何ですか?
- 9. C#のJavaのstring.getBytes()に相当するものは何ですか?
- 10. JavaのgetClass()、isAssignableFrom()などのC#に相当するものは何ですか?
- 11. C#Server.URLEncodeのJavaScriptに相当するものは何ですか?
- 12. iOSのC#ドロップダウンコンボボックスに相当するものは何ですか?
- 13. Visual C++のMy.Resourcesに相当するものは何ですか?
- 14. C#のNSDictionaryに相当するものは何ですか?
- 15. WinRT(C#)のSystem.Diagnostic.Processに相当するものは何ですか?
- 16. JavaのMarshal.ReadIntPtr(IntPtr)(C#)に相当するものは何ですか?
- 17. JavaのThrowableに相当するC#とは何ですか?
- 18. Java DecimalFormatに相当するC#とは何ですか?
- 19. uint32とuint64でOSX、C相当のものは何ですか?
- 20. Objective C "@property(nonatomic、retain)"のC++に相当するものは何ですか?
- 21. iOSフレームワークでLinkedListに相当するものは何ですか?
- 22. 郵便で@ Html.Rawに相当するものは何ですか?
- 23. SilverlightでWinform Control.Handleに相当するものは何ですか?
- 24. MonoTouchでCGImageCreateWithImageInRectに相当するものは何ですか?
- 25. Javascriptでこれに相当するものは何ですか?
- 26. JavascriptのJavaのSystem.out.println()に相当するものは何ですか?
- 27. [Android] JavaのVB.NETの静的キーワードに相当するものは何ですか?
- 28. JavaのSystem.nanoTime()のiOSに相当するものは何ですか?
- 29. 次のJavaペイントコードのAndroidに相当するものは何ですか?
- 30. C++のdynamic_castに相当するC#とは何ですか?
あなたはLinkedHashSetの内容を説明場合には罰金になります:) – demas
これは、挿入順序を維持セットです。バッキングリンクされたリストを使用して行います。 – duffymo
の可能な複製[なぜHashSetがC#で設定されていないのですか?](http://stackoverflow.com/questions/1023697/why-have-hash-but-not-set-in-c) – duffymo