3

思考演習のために、特定のクラスの各インスタンスに属性の一意性をどのように適用できますか?

ここでの一意性は、単一のJVM上にあり、単一のユーザーセッション内にあると定義できます。

これはJavaレベルであり、データベースとは関係ありません。主な目的は、衝突が発生したかどうかを確認することです。

最初の明らかなステップは、クラスレベルで静的属性を持つことです。

  • インスタンスの数が増えるにつれて、ArrayListまたは他のコンテナを持つことは実用的ではないように思われます。
  • クラスレベルで数値カウンタをインクリメントするのが最も簡単な方法のように見えますが、idは常にlast-used-idの後に続く必要があります。
  • ハッシュまたは非数値IDを適用すると問題が発生する可能性があります。
  • 並行性が懸念される場合があります。2つのインスタンスが同時にIDを取得する可能性がある場合は、これを防ぐ必要があります。

この問題にどのように取り組むべきですか?どのような解決策/アプローチがすでに存在する可能性がありますか?

4

3 に答える 3

4

パフォーマンスが気になる場合は、スレッドセーフで高速(ロックフリー)で衝突のないバージョンの一意のID生成を次に示します。

    public class Test {
        private static AtomicInteger lastId = new AtomicInteger();
        private int id;

        public Test() {
            id = lastId.incrementAndGet();
        }
...
于 2013-03-04T05:16:43.583 に答える
3

Java http://docs.oracle.com/javase/6/docs/api/java/util/UUID.htmlUUIDのクラスを使用するだけです。検査中のクラスにタイプ UUID のフィールドを作成し、コンストラクターでこのフィールドを初期化します。

public class Test  {
   public UUID id;
   public Test() {
      id = UUID.randomUUID();
   }
}

衝突を検出するときは、次のようにオブジェクトの UUID の文字列表現を比較するだけです...

Test testObject1 = new Test();
Test testObject2 = new Test();
boolean collision = testObject1.id.toString().equals(testObject2.id.toString());

または、より単純compareTo()にクラスでメソッドを使用しUUIDます...

boolean collision = testObject2.id.compareTo(testObject1.id) == 0 ? true : false;

0 はids が同じであることを意味します。等しくない場合は +1 と -1。

メリット:普遍的に一意(時間ベース、ランダムである可能性があります)であるため、スレッドの問題を処理する必要があります(誰かがこれを確認する必要があります...これは私の知る限りのことです)。詳細については、こちらこちらをご覧ください。

スレッドセーフにするには、SO is java.util.UUID thread safe?に関するこの質問を参照してください。

デメリット: 検査中のクラスの構造を変更する必要があります。つまり、idクラス自体のソースにフィールドを追加する必要があります。これは便利な場合とそうでない場合があります。

于 2013-03-04T05:25:40.317 に答える