59

から要素を取得できない理由を誰かが説明してくれることを願っていますHashSet

とメソッドが正しくオーバーライドされHashSetた のリストを含むことを検討してください。MyHashObjectshashCode()equals()

私がやりたかったことは、MyHashObject自分自身を構築し、関連するハッシュ コード プロパティを特定の値に設定することでした。HashSetメソッドを使用して、セット内に「同等の」オブジェクトがあるかどうかを照会できますcontains()。したがってcontains()、2 つのオブジェクトに対して true が返されても、true ではない可能性があり==ます。

get()では、なぜその仕組みに似た方法がないのcontains()でしょうか。

この API の決定の背後にある考え方を知りたい

4

10 に答える 10

49

取得する要素がわかっている場合は、既にその要素を取得しています。Set要素が与えられた場合、a が答える唯一の質問は、それが要素であるかどうかcontains()です。

要素を反復処理する場合は、単にSet.iterator().

あなたがやろうとしているのは、要素の同等クラスの正規要素を指定しているようです。これには aMap<MyObject,MyObject>を使用できます。ディスカッションについては、この SO の質問またはthis oneを参照してください。

.equals()を使用する必要があるという制約を持つ元の要素を見つけることに本当に決心している場合はHashSet、それを繰り返して自分でチェックすることに固執していると思いますequals()。API では、ハッシュ コードで何かを取得することはできません。したがって、次のことができます。

MyObject findIfPresent(MyObject source, HashSet<MyObject> set)
{
   if (set.contains(source)) {
      for (MyObject obj : set) {
        if (obj.equals(source)) 
          return obj;
      } 
   }

  return null;
}

ブルート フォースと O(n) は醜いですが、それが必要な場合は...

于 2012-08-18T00:09:49.570 に答える
7

基本的に、ハッシュコードをマップのキーとして使用しようとしているようです (これは、HashSets が舞台裏で行うことです)。を宣言することで、明示的に行うことができますHashMap<Integer, MyHashObject>

get通常、パラメーターとしてメソッドに提供するオブジェクトは、返されるオブジェクトと同じであるため、HashSets にはありませんget

于 2012-08-18T00:11:08.807 に答える
6

Set内の要素の順序がわかっている場合は、 SetArrayに変換することでそれらを取得できます。このようなもの:

Set mySet = MyStorageObject.getMyStringSet();
Object[] myArr = mySet.toArray();
String value1 = myArr[0].toString();
String value2 = myArr[1].toString();
于 2015-02-11T22:08:49.907 に答える
3

Set オブジェクト内に含まれるオブジェクトへの参照を取得する必要があるという考えは一般的です。次の 2 つの方法でアーカイブできます。

  1. 必要に応じて HashSet を使用してから、次のようにします。

    public Object getObjectReference(HashSet<Xobject> set, Xobject obj) {
        if (set.contains(obj)) {
            for (Xobject o : set) {
                if (obj.equals(o))
                    return o;
            }
        }
        return null;
    }
    

このアプローチが機能するには、hashCode() メソッドと equals(Object o) メソッドの両方をオーバーライドする必要があります。最悪のシナリオでは、O(n) があります。

  1. 2番目のアプローチは、TreeSetを使用することです

    public Object getObjectReference(TreeSet<Xobject> set, Xobject obj) {
        if (set.contains(obj)) {
            return set.floor(obj);
        }
        return null;
    }
    

このアプローチは、より効率的な O(log(n)) を提供します。このアプローチでは hashCode をオーバーライドする必要はありませんが、 Comparable インターフェイスを実装する必要があります。( 関数 compareTo(Object o) を定義します)。

于 2016-08-27T19:11:13.053 に答える
1

私のアプリケーションで、オブジェクトがリストまたはハッシュデータ構造の検索で使用されておらず、追加中にハッシュデータ構造で間接的に使用されたものを除いて、他の場所で equals メソッドを使用していないことが確実にわかっている場合。equals メソッドで設定された既存のオブジェクトを更新することをお勧めします。以下のコードを参照してください。this Bean を HashSet に追加すると、キー (id) で一致するオブジェクトに対してグループ集約を行うことができます。このようにして、合計、最大、最小などの集計関数も実現できます。お勧めできない場合は、お気軽にご意見をお聞かせください。

public class MyBean {

    String id,
           name;
    double amountSpent;

    @Override
    public int hashCode() {
        return id.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if(obj!=null && obj instanceof MyBean ) {
            MyBean tmpObj = (MyBean) obj;
            if(tmpObj.id!=null && tmpObj.id.equals(this.id)) {
                tmpObj.amountSpent += this.amountSpent;
                return true;
            }
        }
        return false;
    }
}
于 2015-07-22T03:31:10.623 に答える
1

まず、セットを配列に変換します。次に、配列のインデックスで項目を取得します。

Set uniqueItem = new HashSet() ;
uniqueItem.add("0");
uniqueItem.add("1");
uniqueItem.add("0");

Object[] arrayItem = uniqueItem.toArray(); 
for(int i = 0; i < uniqueItem.size();i++){
    System.out.println("Item "+i+" "+arrayItem[i].toString());
}
于 2018-02-04T06:26:38.467 に答える
0

ListMap の値に結果を格納する代わりに、データ構造として使用できる場合Mapは、次のスニペットを使用して結果を同じオブジェクトに格納できます。

以下はNodeクラスです。

private class Node {
    public int row, col, distance;

    public Node(int row, int col, int distance) {
        this.row = row;
        this.col = col;
        this.distance = distance;
    }

    public boolean equals(Object o) {
        return (o instanceof Node &&
                row == ((Node) o).row &&
                col == ((Node) o).col);
    }
}

結果を距離変数に保存し、リスト内の項目が座標に基づいてチェックされる場合、1 つの要素のみを保存する必要がある限り、次の方法を使用してlastIndexOfメソッドを使用して距離を新しいものに変更できます。各データについて:

    List<Node> nodeList;
    nodeList = new ArrayList<>(Arrays.asList(new Node(1, 2, 1), new Node(3, 4, 5)));
    Node tempNode = new Node(1, 2, 10);
    if(nodeList.contains(tempNode))
        nodeList.get(nodeList.lastIndexOf(tempNode)).distance += tempNode.distance;

基本的にSet、誰のアイテムにアクセスして変更できるかを再実装しています。

于 2016-03-06T23:08:34.657 に答える