11

値引数のみで追加またはプッシュを行うと、自動的にインデックスが返される ArrayList に似た Java データ構造を探しています。

例えば:

ArrayList<String> elements = new ArrayList<String>();

String element = "foo";
String elementTwo = "bar";

int index1 = elements.add(element); //note this does not exist, i.e. returns bool in api
int index2 = elements.add(elementTwo);

System.out.println(elements.get(index1)); //would give "foo"

追加操作ごとにインクリメントされるカウンターを管理する ArrayList の周りにラッパー クラスを作成し、次の呼び出しを行うことがわかりました。

ArrayList.add(int index, E element)

このために ArrayList のラッパーを本当に書く必要がありますか? これは、箱から出してどこかで提供できるほど単純なもののように思えますか?

編集:

このユースケースでは、インデックス (キー) を固定して一意にする必要があります。地図が提案され、私はそれに同意します。値の挿入時に自動的に (一意に) 生成されたキーを提供するマップの実装を知っている人はいますか? これに独自のラッパーを実装する必要があるかどうかを判断しようとしています。

4

5 に答える 5

7

要素はリストの最後に追加されます。したがってelements.size()-1、新しい要素のインデックスを取得するために使用できます。

複数のスレッドが同時にリストを変更している場合、これは確実に機能しないことに注意してください。

編集:またArrayList、要素のインデックスは変更される可能性があるため (たとえば、要素を削除したり、新しい要素を挿入したりする場合)、一意の ID として s インデックスを使用することはお勧めできませんadd(int, Object)。これが問題になるかどうかは、インデックスで何をしたいかによって異なります。要素を追加した後の短時間だけ必要で、その間リストが変更されていないことを確認できる場合は、問題はありません。それ以外の場合、呼び出し時にインデックスを返すメソッドでさえ、add(Object)インデックスが更新されないため役に立ちません。この問題を回避するには、次のことができます。

  • リストから要素を削除したり、 を使用して要素を追加したりしないでくださいadd(int, Object)
  • 要素を削除する代わりにnull、メソッドを使用して要素を設定することもできますset(int, null)。この方法では、要素のインデックスは変更されません。
  • たとえば、helloannalil が彼の回答で示唆しているようなカスタム ID を持つマップなど、他のデータ構造を使用します。

編集 2:すぐに使用できる適切な実装が見つかりませんでした (ただし、もちろん、何もないという意味ではありません)。適切な解決策を提案するには、データ構造の使用目的に関する詳細情報が必要ですが、いくつかのアイデアと注意事項を次に示します。

  • 要素の最大数がそれほど多くない場合は、 をArrayList使用でき、要素インデックスは ID を表します。上記のように、要素を削除するにはnull、インデックスが変更されないように設定できます。挿入時に、null値のある位置を再利用できます。
  • この回答に示されている 2 つの方法のいずれかを使用することもできます: https://stackoverflow.com/a/8939049/1347968 (キーワードAtomicLongまたはIdentityHashMap)
  • orの「一意性」は保証されていないため、依存しないでください( Suns/Oracles Bug #6321873の下部にある例を実行してみてください)。Object.hashCode()System.identityHashCode(Object)
于 2012-04-25T03:44:02.877 に答える
2

あなたのコメントと編集された質問に基づいて、私はあなたがこのようにあなたの使用のためにHashMapを拡張することができると思います:

public class MyMap<V> extends HashMap<Integer, V> {
    private static final long serialVersionUID = 1L;
    public int add(V elem) {
        int key = System.identityHashCode(elem);
        super.put(key, elem);
        return key;
    }
}

MyMap次に、クラス内で次のように宣言します。

private MyMap<String> map = new MyMap<String>();

そして、次のように要素を追加しますMyMap

.....
.....
String element = "foo";
String elementTwo = "bar";
int index1 = map.add(element);
int index2 = map.add(elementTwo);

これで、アプリケーションの存続期間中に使用または渡すことができる文字列を挿入したインデックスができましたindex1。要素は何度でもindex2挿入または削除できますが、インデックス(および)を使用すると、挿入された要素が次のように返されます。MyMapindex1index2

String elem1 = map.get(index1); // will return "foo"
String elem2 = map.get(index2); // will return "bar"
于 2012-04-25T20:30:33.793 に答える
2

その場合に私が行うこと (私は ArrayLists が大好きです) は、リストのサイズを尋ねて最後のインデックスを取得することです。

String thing = "theThing";
List<String> strList = new ArrayList<String>();
strList.add(thing);
int indexOfThing = strList.size() - 1;

つまり、独自のリストを実装するよりも簡単で、うまく機能します。

于 2012-04-25T03:44:32.270 に答える
2

本当にこの機能が必要な場合は、リストではなくマップを使用できます

于 2012-04-25T03:48:25.080 に答える
0
String thing = "theThing";
List<String> strList = new ArrayList<String>();
strList.add(thing);
int indexOfThing = strList.size() - 1;

アイテムを削除すると、これは機能しなくなります。

于 2014-09-20T07:29:02.947 に答える