1

最も効率的かつ効果的な方法で定期的に持っている Java オブジェクトのリストを更新するアルゴリズムを探しています。アルゴリズムは...

現在のセット

A, B, C

リロード命令が呼び出され、DB から新しいセットが返されます

A, C, D

(つまり、 A&Cは (必要に応じて) 更新するB必要があり、削除する必要があり、&Dは新しく、作成する必要があります)

明らかに、すべてのオブジェクトを強制終了して、毎回すべてを再作成することができますが、変更されていないオブジェクトを強制終了することは避けたいです (つまり、DB でA&が変更されていない場合は、現在の Java &オブジェクトをそのままにして続行する必要があります)。現在の姿で)。CAC

これらのさまざまなチェックを行い、必要に応じて追加/更新/削除する優れたアルゴリズムが必要です。私の状況のロジックは、ArrayList<String>明らかに私のオブジェクトがはるかに複雑であるため、単純な例から引き継ぐことができるはずです。ABC

4

4 に答える 4

1

HashMapデータベース ID をキーとして、完全なオブジェクトを値として持つが必要です。結果セットを反復処理し、O(1) 操作によって、項目が既に存在するかどうかを確認します。その後、必要に応じて追加および更新できます。先に進むにつれて、HashSet取得したすべてのエントリのデータベース キーの一時キーを作成します。次に、最終セット差分を実行して、ランタイム コピーから削除するアイテムを見つけます。

于 2013-01-02T10:30:03.317 に答える
0

BusinessLayer 用と UI レイヤー用の 2 つのリストを作成し、それに応じてオブジェクトを作成/更新/削除するようにマークすることができます。このマークされたリストが識別されると、それに応じて DB のクエリを作成するために転送できます。

于 2013-01-02T10:29:30.693 に答える
0

セットにはマップを使用することをお勧めします。これにより、検索がより効率的になります。

いくつかのループを実行して、何が変更されたかを確認できます。

Map<MyKey, MyType> previous = ..
Map<MyKey, MyType> current = ..

for(Map<MyKey, MyType> entry: current.entrySet()) {
  MyType t = entry.getValue();
  MyType p = previous.get(entry.getKey());
  if (p == null)
      added(t);
  else if (!p.equals(t))
      updated(p, t);
}
for(Map<MyKey, MyType> entry: previous.entrySet()) {
  if(!current.contains(entry.getKey()))
     removed(entry.getValue());
}
于 2013-01-02T10:30:46.063 に答える
0

解決策 1

オブジェクトは、次のような基本型から継承できます。

abstract class PersistentObject {
    private boolean persistent;  // true if exists in database
    private boolean modified;    // true if modified
    private boolean deleted;     // true if deleted

    public boolean isPersistent() { return persistent; }
    protected void setPersistent() { persistent = true; }

    public boolean isModified() { return modified; }
    protected void setModified() { modified = true; }

    public boolean isDeleted() { return deleted; }
    protected void setDeleted() { deleted = true; }
}

また、オブジェクトを操作するときに、オブジェクトの状態を呼び出したり変更したりします。例えば ​​:

public void setSomeIntvalue(int value) {
    this.value = value;

    setModified();
}

変更をコミットする (セットを反復処理する) と、DELETE削除されたオブジェクトがデータベースから削除され、セットから削除されます。が false の場合isPersistent()は新しいものを作成し、isModified()true の場合はそれを作成UPDATEし、それ以外の場合は何もしません。

解決策 2

オブジェクトのセットを管理するためのラッパーを持つことができます。何かのようなもの :

abstract class AbstractEntitySet<E> {
    private HashSet<E> createdSet = new HashSet<E>();
    private HashSet<E> modifiedSet = new HashSet<E>();
    private HashSet<E> deletedSet = new HashSet<E>();

    public void add(E e) {
        add(e, false);
    }

    public void add(E e, boolean modified) {
        if (modified) {
            createdSet.remove(e);
            modifiedSet.add(e);
            deletedSet.remove(e);
        } else {
            createdSet.add(e);
            modifiedSet.remove(e);
            deletedSet.remove(e);
        }
    }

    public void remove(E e) {
        createdSet.remove(e);
        modifiedSet.remove(e);
        deletedSet.add(e);
    }

    public void applyChanges() {
        for (E e : createdSet) {
            createEntity(e);
        }
        createdSet.clear();

        for (E e : modifiedSet) {
            updateEntity(e);
        }
        modifiedSet.clear();

        for (E e : deletedSet) {
            deleteEntity(e);
        }
        deletedSet.clear();
    }

    protected abstract void createEntity(E e);
    protected abstract void updateEntity(E e);
    protected abstract void deleteEntity(E e);
}

このセットをオブジェクトに直接バインドすることもできます:

abstract class BaseEntity<E> {
    private AbstractEntitySet<E> connectedSet;

    @SuppressWarnings("unchecked")
    public E bindTo(AbstractEntitySet<E> set) {
        connectedSet = set;
        return (E) this;
    }

    @SuppressWarnings("unchecked")
    public void setCreated() { connectedSet.add((E) this, false); }
    @SuppressWarnings("unchecked")
    public void setModified() { connectedSet.add((E) this, true); }
    @SuppressWarnings("unchecked")
    public void setDeleted() { connectedSet.remove((E) this); }
}

オブジェクトを宣言する場所(たとえば):

class SomeObject extends BaseEntity<SomeObject> { 
    public void setSomeThing(...) {
        ...
        setModified();
    }
}

次のような新しいインスタンスを作成します

AbstractEntitySet<SomeObject> entitySet = ...;
...
SomeObject obj = new SomeObject().bindTo(entitySet);

次に、オブジェクトを更新し、次のようなすべての変更を適用します

obj.setSomeThing(...);
...
entitySet.applyChanges();

解決策 3

アプリケーションでHibernateJPAなどの既存の永続化レイヤーを使用することもできます。

于 2013-01-02T10:34:59.863 に答える