4

次のように、1 つ以上のキー文字列をオブジェクトにマップするメモリにデータを格納する必要があります。

"green", "blue" -> object1
"red", "yellow" -> object2

したがって、Java では、データ構造は以下を実装する可能性があります。

Map<Set<String>, V>

文字列が次のようなブール値の基準に一致するオブジェクトのリストを効率的に受信できるようにする必要があります。

("red" OR "green") AND NOT "blue"

私は Java で作業しているので、理想的なソリューションは既製の Java ライブラリです。ただし、必要に応じてゼロから何かを実装したいと考えています。

誰にもアイデアはありますか?可能であれば、メモリ内データベースのオーバーヘッドを避けたいと思います.HashMapに匹敵する速度(または少なくとも同程度)を望んでいます。

4

9 に答える 9

6

実際、私はこの問題が好きだったので、以前の回答の精神で完全な解決策を実装しました。

http://pastebin.com/6iazSKG9

スレッドセーフでも何でもないシンプルなソリューションですが、楽しくて良い出発点だと思います。

編集:要求に応じて、いくつかの詳細


使用法については単体テストを参照してください。

と の 2 つのインターフェイスがありDataStructure<K,V>ますQuery<V>。DataStructure はマップのように動作します (私の実装では、実際には内部マップで動作します) が、次のように組み合わせることができる再利用可能で不変のクエリ オブジェクトも提供します。

    Query<String> combinedQuery = 
    structure.and(
                    structure.or(
                            structure.search("blue"), 
                            structure.search("red")
                    ),
                    structure.not(
                            structure.search("green")
                    )
    );

((blue OR red) AND NOT green としてタグ付けされたオブジェクトを検索するクエリ)。このクエリは再利用可能です。つまり、バッキング マップが変更されるたびに結果が変更されます (ITunes スマート プレイリストのようなものです)。

クエリ オブジェクトは既にスレッド セーフになっていますが、バッキング マップはそうではないため、ここには改善の余地があります。また、クエリは結果をキャッシュすることもできますが、それはおそらく、パージ メソッド (Wicket のモデルの detach メソッドのようなもの) を提供するためにインターフェイスを拡張する必要があることを意味します。

ライセンスに関して: もし誰かがこのコードを欲しがっていたら、喜んで SourceForge などに載せます...

ショーン

于 2010-05-20T15:50:14.967 に答える
1

基準はビットマップ インデックス作成に適していますか: http://en.wikipedia.org/wiki/Bitmap_index ?

于 2010-05-20T13:36:52.263 に答える
0

文字列キーをバイナリ定数にマップし、ビット シフトを使用して適切なマスクを生成できます。

于 2010-05-20T16:00:11.593 に答える
0

最も簡単な方法は、単純に再帰的なフィルタリングを行い、クリーバーになることです。たとえば、 が空のセットに評価されたX AND Y場所を評価する場合です。X

ただし、マッピングはタグ(「赤」や「青」など) からオブジェクトのセットへのマッピングである必要があります。

再帰の基本ケース (アトミック タグの解決) は、このマップでの単純な検索になります。AND交差点、ORユニオンなどを使用して実装されます。

于 2010-05-20T13:34:34.840 に答える
0

満足のいく解決策を見つけることができなかったので、自分で作成してオープン ソース (LGPL) プロジェクトとしてリリースすることにしました

于 2010-07-15T17:26:38.573 に答える
0

Apache Commons-Collections プロジェクトを調べてください。それらには、強力なコレクションベースのロジックを実行するためのCollectionUtilsクラスなど、使用できる優れた機能がたくさんあります。

たとえば、値が HashMap に格納されている場合 (別の回答で示唆されているように)、次のようになります。

myMap["green"] -> obj1
myMap["blue"] -> obj1
myMap["red"] -> obj2
myMap["yellow"] -> obj2

次に、一致する結果を取得するには、次のように("red" or "green") and not "blueします。

CollectionUtils.disjunction(CollectionUtils.union(myMap.get("red"), myMap.get("green")), myMap.get("blue"))

于 2010-05-20T13:46:44.190 に答える
0

Google コレクションのSetMultimapは、基になる構造を取得し、それをマップの静的フィルターと組み合わせて、必要なクエリ動作を取得する簡単な方法のように見えます。

建設は次のようになります

smmInstance.put(from1,to1);
smmInstance.put(from1,to2);
smmInstance.put(from2,to3);
smmInstance.put(from3,to1);
smmInstance.put(from1,to3);
//...

クエリは次のようになります

valueFilter = //...build predicate
Set<FromType> result = Maps.filterValues(smmInstance.asMap(),valueFilter).keySet()

述語をいくらでも作成できますが、Predicatesには、contains/doesn't contain スタイル クエリを実行するのにおそらく十分なメソッドがいくつかあります。

于 2010-05-20T17:36:01.770 に答える
0

ある種のデータベース ソリューションが最善の策だと本当に思います。SQL は、データのクエリを簡単にサポートします。

(X and Y) and not Z
于 2010-05-20T16:08:01.507 に答える
0

これはうまくいくだろう再利用可能な条件/式クラス

于 2010-05-20T16:33:37.487 に答える