なぜすることはできないのでしょうかを取得項目から、HashSetなく列挙?
質問
私の見解するヘッドのパラメータは、HashSetにデザイナー。どんもご承知のように、私の質問の両方に適用されることもJavaとC#のHashSets、思いがある理由でも思いつかないのです。
をして頂いた後に挿入した項目へのパラメータは、HashSetに、なぜことは不可能な取得する項目なく列挙、ほとんど効率的な働きかけているのか?特にこのパラメータは、HashSetに明示的に構築に対応した効率的な検索を行うのかについて
いく役に立って削除(x)を含む(x)を返します実際のアイテムが削除され又は含まれています。このような項目をいパスを削除(x)の成を目指しております。(x)機能を搭載しています。確かないといけないと思い、私達と同様の効果を通じて、HashMapがなぜ廃棄物のすべての空間と労力が必要で完璧にできること。
できることができるので、あるデザインの懸念を追加することにより機能が利用できるのHashSet性の役割や将来の枠組みだこになっていますので、このデザインの懸念?
編集
答えによらもより長く、より多くの問題を、より詳細:
を使用している不変なので参考タイプオーバーライドhashcode、equalsなどをエミュレートする値型のC#.そうすることで型には会員A,B,C.Hashcode、equalsなどにのみ依存するA及びBもたらされたAとBのこういうことができるように取得すること等から、hashsetとでC.い利用できHashSetこれには、少なくとも知がある場合もありました。擬似コード:
public sealed class X{
object A;
object B;
object extra;
public int HashCode(){
return A.hashCode() + B.hashCode();
}
public bool Equals(X obj){
return obj.A == A && obj.B == B;
}
}
hashset.insert(new X(1,2, extra1));
hashset.contains(new X(1,2)); //returns true, but I can't retrieve extra
解決
どのようにして、ハッシュセットからアイテムを取得することを提案したのですか?セットはどのような方法で注文しない定義であるため、問題のオブジェクトを取得するために使用するとは、インデックスはありません。
セットは、概念として、封入、すなわち、当該要素は、ハッシュデータセットであるか否かを試験するために使用されます。あなたがキー値またはインデックスを使用して、データソースから値を取得するために探しているなら、私はどちらか<のhref = "http://java.sun.com/javase/6/docs/api/に探してお勧めしますJavaの/ utilに/ Map.html "のrel = "noreferrer">地図のか<のhref =" http://java.sun.com/javase/6/docs/api/java/util/List。 HTML」のrel = "noreferrer">リストでます。
の編集:元の質問に編集に基づいて追加の答えの
新しい情報に基づいてSoonil、あなたはJavaの列挙、これに似たものとして、あなたのデータを実装するに興味があるかもしれないように見えます:
public enum SoonilsDataType {
A, B, C;
// Just an example of what's possible
public static SoonilsDataType getCompositeValue(SoonilsDataType item1,
SoonilsDataType item2) {
if (item1.equals(A) &&
item2.equals(B)) {
return C;
}
}
}
enumのは自動的に設定と同じように反対含めることをテストするために使用できる列挙型の「セット」内のすべての値のリストを、返す値を()を継承。また、その完全なクラスので、あなたは(私はサンプルコードでにほのめかすしようとしていたように)複合ロジックを実行するために新しい静的メソッドを定義することができます。列挙型についての唯一のものは、(セットのデータサイズは、実行時に成長するつもりはない場合も、列挙型は、あなたが望むものである)あなたが望むものではない可能性がある、実行時に新しいインスタンスを追加することはできませんということです。
他のヒント
.NETで、あなたはおそらく探しているものは、KeyedCollectionです http://msdn.microsoft.com/en-us/library/ms132438.aspx の
あなたは、いくつかの「一般的な」賢さを再実装この抽象クラスの意地の悪の周りにそれぞれの時間を得ることができます。 (IKeyedObject`1を参照してください。)
注:IKeyedObject`1を実装する任意のデータ転送オブジェクトは、単にthis.Key.GetHashCode()を返すオーバーライドGetHashCodeメソッドを有するべきです。そして同じことが対等のために行く...
私の基本クラスライブラリは、通常、その中にこのようなもので終わる:
public class KeyedCollection<TItem> : System.Collections.ObjectModel.KeyedCollection<TItem, TItem>
where TItem : class
{
public KeyedCollection() : base()
{
}
public KeyedCollection(IEqualityComparer<TItem> comparer) : base(comparer)
{
}
protected override TItem GetKeyForItem(TItem item)
{
return item;
}
}
public class KeyedObjectCollection<TKey, TItem> : System.Collections.ObjectModel.KeyedCollection<TKey, TItem>
where TItem : class, IKeyedObject<TKey>
where TKey : struct
{
public KeyedCollection() : base()
{
}
protected override TItem GetKeyForItem(TItem item)
{
return item.Key;
}
}
///<summary>
/// I almost always implement this explicitly so the only
/// classes that have access without some rigmarole
/// are generic collections built to be aware that an object
/// is keyed.
///</summary>
public interface IKeyedObject<TKey>
{
TKey Key { get; }
}
、それのハッシュは(のhashCode()がオーバーライドされた場合、これは特にそうである)変更された可能性があります。ハッシュが変更された場合、あなたはそれが中に保存されているよりも、別の場所でハッシュ化されたオブジェクトを検索しようとするように、セットでのそれのルックアップは、失敗します。
また、あなたがのhashCodeをオーバーライドして、あなたが別のインスタンスである同じオブジェクトを検索したい場合は、あなたのオブジェクトのequalsしていることを確認する必要があります。
これはJavaのためのすべてであることに注意してください - 私はC#は似た何かを持っていると仮定していますが、それは、私はC#]を使用するので、数年が経ちましたように、私は他の人がそれに話すようになる機能です。
。私はSet
インターフェースとHashSet
クラスのデザイナーを想像することはremove(Object)
インタフェースで定義されたCollection
方法もSet
に適用可能であったことを確認するために望んでいました。このメソッドは、オブジェクトが正常に削除されたかどうかを示すブール値を返します。設計者は、削除(オブジェクト)Set
既に「等しい」オブジェクトを返される機能を提供したい場合、これは、異なるメソッドシグネチャを意味する。
また、除去されるオブジェクトが含まれているオブジェクトを返すに付加価値について議論の余地ある(Object)を除去するために、渡されたオブジェクトと論理的に同等であることを考えます。しかし、私は自分の前にこの問題を抱えているし、問題を解決するために地図を使用しています。
Javaで、HashSet
が内部HashMap
を使用するので、代わりHashMap
を使用して追加のストレージオーバーヘッドがないことに注意してください。
なぜちょうどHashMap<X,X>
を使わないのでしょうか?これは正確に何をしたいん。ただ、毎回.put(x,x)
行い、その後、あなただけの.get(x)
とxに等しい保存された要素を取得することができます。
このた監督からの図書館のデザイナー。っており、下 他の答え, この方法が追加されている .NETフレームワーク4.7.2.使用量の制限 ( .ネコ2.0 で);見 HashSet<T>.TryGetValue
.引用 のソース:
/// <summary>
/// Searches the set for a given value and returns the equal value it finds, if any.
/// </summary>
/// <param name="equalValue">The value to search for.
/// </param>
/// <param name="actualValue">
/// The value from the set that the search found, or the default value
/// of <typeparamref name="T"/> when the search yielded no match.</param>
/// <returns>A value indicating whether the search was successful.</returns>
/// <remarks>
/// This can be useful when you want to reuse a previously stored reference instead of
/// a newly constructed one (so that more sharing of references can occur) or to look up
/// a value that has more complete data than the value you currently have, although their
/// comparer functions indicate they are equal.
/// </remarks>
public bool TryGetValue(T equalValue, out T actualValue)
Map<X,Y>
のタイプであるextra1
、探しているように、私には見えます。
<時間>(以下暴言)
のequalsとhashCodeメソッドは、意味のあるオブジェクトの等価を定義します。 HashSetのクラスはObject.equals(Object)
によって定義される2つのオブジェクトが等しい場合は、これら2つのオブジェクト間の差がないことを前提としています。
私はobject extra
は意味がある場合は、あなたのデザインが理想的ではないことを言って限り行くと思います。
を解決しようの。検索に使用される代表的で見つかった要素と異なる場合がありますので、要素を検索したいことは、私には完全に有効と思われます。要素はキーと値の情報が含まれており、カスタム等値比較が唯一の重要な部分を比較した場合、これは特にそうです。コード例を参照してください。コードは、カスタム検索とを実装した比較演算子が含まれていますの見つかった要素をキャプチャしています。これは、比較演算子のインスタンスが必要です。見つかった要素への参照をオフにします。含まれていによる検索を実行します。見つかった要素にアクセスします。比較演算子のインスタンスを共有する場合、マルチスレッドの問題に注意してください。
using System;
using System.Collections.Generic;
namespace ConsoleApplication1 {
class Box
{
public int Id;
public string Name;
public Box(int id, string name)
{
Id = id;
Name = name;
}
}
class BoxEq: IEqualityComparer<Box>
{
public Box Element;
public bool Equals(Box element, Box representative)
{
bool found = element.Id == representative.Id;
if (found)
{
Element = element;
}
return found;
}
public int GetHashCode(Box box)
{
return box.Id.GetHashCode();
}
}
class Program
{
static void Main()
{
var boxEq = new BoxEq();
var hashSet = new HashSet<Box>(boxEq);
hashSet.Add(new Box(3, "Element 3"));
var box5 = new Box(5, "Element 5");
hashSet.Add(box5);
var representative = new Box(5, "Representative 5");
boxEq.Element = null;
Console.WriteLine("Contains {0}: {1}", representative.Id, hashSet.Contains(representative));
Console.WriteLine("Found id: {0}, name: {1}", boxEq.Element.Id, boxEq.Element.Name);
Console.WriteLine("Press enter");
Console.ReadLine();
}
}
} // namespace
これらの言語のSetオブジェクトはほとんどない可変オブジェクトのために、値のセットとして設計されていました。彼らは彼らに入れたオブジェクトに等しいを使用して一意であることを確認してください。返すブール値ではなく、オブジェクトが含まれており、削除理由は、次のとおりです。彼らはのために確認するか、あなたがそれらに渡す値を削除する
そして、あなたがしなければ実際には、セットに(X)を含有し、そしてだろうが、XとYは(すなわちX.equals(Y)=> true)をイコールであることを意味別のオブジェクトYを、取得できると期待したが、多少間違っ思われる、異なるます。
私は自分のオブジェクトがKeyValuePairsとして自分自身を定義することによって、地図を使用する方法に関して、興味深い示唆を与えました。良いコンセプトが、残念ながらKeyValuePairはインタフェースではありません(なぜ?)と空気のうち、その計画を放つ構造体、です。私の制約が私にこのオプションを許可するよう最後に、私は、私自身のセットをロールバックされます。
短い答え。アイテムは不変であることを保証することはできませんので。
私はハッシュコードがメンバークラス内の固定フィールドに基づいていますが、記述の正確な問題を、ヒットしましたが、このクラスは、ハッシュを変更せずに更新することができ、追加の情報を保持します。
私のソリューションは、一般的なMyHashSetを実装するために、
ソースコードを見ることができること細かく同じことを思って、そして後:
ソース: http://referencesource.microsoft.com /#System.Core/System/Collections/Generic/HashSet.csする
のセットは、一意のアイテム(オブジェクトまたは値)の集合です。比較器のEqualsメソッドは、2つの項目にtrueを返す場合、.NETの実装では、項目別のアイテム(一意ではない)と同じです。 2つの項目が同じハッシュコードを持っていない場合。そう項目の有無の確認は、二段階プロセスです。最初COMPEREするアイテムの数を最小限にするためにHashSetのを使用して、次に圧縮自体
あなたがアイテムを取得したい場合は、は、一意の識別子と検索機能を提供できなければなりません。あなたがしたい項目のハッシュコードを知っている可能性があります。しかし、それは十分ではありません。複数のアイテムと同じハッシュを持つことができます。あなたはまた、均等法を呼び出すことができるように、アイテム自体を供給する必要があります。あなたがアイテムを持っている場合は、はっきりとそれを得るために理由はありません。
一つは、どの2つのユニークなアイテムはこれまでと同じハッシュコードを返さないことを要求するデータ構造を作成することができます。そして、あなたはそれからアイテムを得ることができるよりも。それは*を追加するより速くなり、そしてあなたがハッシュを知っていれば検索が可能になります。等しくないが、同じハッシュを返す2つのアイテムが、それに入れている場合は、最初は上書きされます。私の知る限りでは、このタイプは、.NETに存在しない、無これは辞書と同じではありません。
* GETHASH方法が同じであることを考えます。