Java での述語検索
-
22-09-2019 - |
質問
この質問をどのように言葉で表現すればよいのかよくわかりません。カスタム Java クラスの特定の部分をチェックして、特定の基準に一致するかどうかを確認する方法があるかどうか疑問に思っています。このような
public Name(String forename, String middlename, String surname)
そして、そのクラスのインスタンスの配列が作成されると、次のようになります。
Name[] applicants = new Name[4];
applicants[0] = new Name("john","bob", "rush");
applicants[1] = new Name("joe","bob", "rushden");
applicants[2] = new Name("jack","bob", "rushden");
applicants[3] = new Name("jake","bob", "rushden");
クラスのインスタンスに対して次のような人を検索することはできますか?
midddlename.equals("bob") && surname.equals("rush")
私は実際に解決策を探しているわけではありません if(surname.equals("bob")) then else
、等
ただし、配列の迅速な検索を可能にする組み込み Java クラスです。この速度は非常に重要です。
解決
サポートは組み込まれていませんが、 Apache コレクション そして Google コレクション どちらもコレクションに対する述語のサポートを提供します。
見つかるかもしれません この質問 そしてその答えは役に立ちます。これも同じ 開発者.com 記事。
例えばGoogle コレクションの使用:
final Predicate<name> bobRushPredicate = new Predicate<name>() {
public boolean apply(name n) {
return "bob".equals(n.getMiddlename()) && "rush".equal(n.getSurname());
}
}
final List<name> results = Iterables.filter(applicants, bobRushPredicate));
他のヒント
は、配列を検索し、実際に一緒に行かない「スピードは非常に重要です」。あなたの配列が非常に小さくなる場合、配列を検索する場合を除き、迅速になることはありません。これは、データベースの全表スキャンと同等である、パフォーマンスは関係なく、あなたがそれについて移動する方法が悪いことはないだろう。すぐに物事を見つけるための鍵は、インデックス付きの構造を使用することです。あなたは絶対にそれを必要とする場合は、まだ配列を持つことができますが、検索は別のデータ構造を使用して行われるべきです。彼らはそれが非常に高速取得するために作る方法でデータを整理するため、ハッシュやツリーベースのコレクションをチェックしてください。 TreeSetの、TreeMapの、HashSetの、HashMapの、ハッシュされたキーの上などハッシュインデックスデータ、木は似ていますが、またソートされた順序でそのデータを格納します。
apache common ArrayUtils
以上のオブジェクトの等価性に基づいて検索する必要がある場合は、、あなたは基本的に名前のオブジェクトのためのあなたのequalsとhascodeをオーバーライドし、それを使用する必要がありますが、カスタム基準を検索に使用したい場合は、私はあなたが実装する必要が推測します独自の方法とそこにはJava言語のサポートが組み込まれている。
使用 Apache Derbyをのか<のhref = "HTTPのようなメモリ内のデータベース:// hsqldb.org/」のrel = "nofollowをnoreferrer"> HSQLDB を。 JDBC、JPA、または休止状態を活用して、すべてのあなたがやりたいことができます。
あなたのコードのプロファイルを作成します。そして、最適化ます。
こうして私が考えられることはい作成するデータ構造のミラーはこの物性値を内部毎にインデックス値。
た値が検索され、この内部データ構造に戻り、指数をバイナリを検索する
唯一の要件は対象者の登録および更新となります。
には、次のようなものが想像上のUML/Pythonのようなコード:
// Holds the index number of a given value
// for instance, name="Oscar" may be at index 42...
IndexValuePair
index : Int
value : String
+_ new( value: String, index: Int )
return IndexValuePair( value, index )
ValuePairComparator --> Comparator
+ compareTo( a: IndexValuePair, b: IndexValuePair ) : Int
return a.value.compareTo( b.value )
SearchStructure
- data = Object[] // The original array which contains your applicants
// a list of arrays each one containing the property value, and the index on "data" where that value appears
- dataIndexes = List(IndexValuePair)[String] // Map<List<IndexValuePair>>
- dataIndexexInitialized = false
// Add an object to this structure
+ addObject( o: Object )
if( ! dataIndexesInitialized,
initIndexesWith( o )
)
index = data.add( o ) // returns the index at which "o" was inserted
addToIndexes( o, index )
// Register all the properties values of the given object
// along with the index where they appear in the original array
- addToIndexes( object: Object, index: Int )
forEach( property in Object ,
list = dataIndexes[property]
list.add( IndexValuePair.new( property.value, index ) )
)
// Create empty array for each property ..
- initIndexesWith( object : Object )
forEach( property in object ,
comparator = ValuePairComparator()
list = List<IndexValuePair>()
list.setComparator( )
dataIndexes[property] = list
)
dataIndexesInitialized = true
// Search an object using the given criteria ( a Map<String, String> = key=value )
+ search( criteria: String[String] ) : List<Object>
result = Set<Object>()
// let's say criteria has:
// ["name":"Oscar", "lastName"="Reyes"]
forEach( key in criteria,
list = dataIndexes[key] // "name", "lastname" ..etc.
valuePair = list.binarySearch( criteria[key] ) // first Oscar, later Reyes
result.add( data[valuePair.index] )
)
return result
マット
これは理解できなければならない。
そのポイントは、何をして本当に速いのは、この指標による財産
- 配列のデータ
- 配列の各物件に、との考えを示して指数のデータ
のためのインスタンスの場合、以下の配列:
a = [ Object(name="Mike", lastName="Z" )
Object(name="Oscar", lastName="Reyes" ) ,
Object(name="Rahul", lastName="G" ) ,
Object(name="Pie", lastName="154" ) ]
いのポジション:
0 = Mike ...
1 = Oscar ...
2 = Rahul ...
3 = Pie ...
だい(この場合)別の配列を後にソートすることはできない。
nameArray = ["Mike=0", "Oscar=1", "Pie=3", "Rahul=2"]
や
lastNameArray = ["154=3", "G=2", "Reyes=1", "Z=0"]
検索するときに指定された属性に対応する配列、例えばwanの検索の最後の名前"スレイエス"きょう"lastName"配列
["154=3", "G=2", "Reyes=1", "Z=0"]
を有することでbinarySearchしていると、その"スレイエス"の要素を返しますポジション2、返却指数=1whihの位置"オスカー"は、元の配列になります。
こういっO(log n)
ParallelArray クラスを見ると、要件は満たされていますが、これを効率的に使用するには、関数型プログラミングの概念を少し学ぶ必要があります。
このクラスには JDK 6 が付属していませんが、JDK 7 が付属する可能性があります (議論中)。一方、ライブラリとして使用することもできます。JSR166y パッケージを次からダウンロードします。http://gee.cs.oswego.edu/dl/concurrency-interest/
詳細な説明については、このチュートリアルを参照してください。http://www.ibm.com/developerworks/java/library/j-jtp03048.html
複雑に聞こえるかもしれませんが、実際はそうなのです (高性能のマルチスレッド アルゴリズムを詳しく調べているだけの場合)。よりユーザーフレンドリーな API を Parallel Array にラップしようとする Groovy プロジェクトがあるので、それも見てみるとよいでしょう。 http://gpars.codehaus.org/ , http://gpars.codehaus.org/Parallelizer
Javaの8つの追加ラムダ式とストリームAPI、サポートが内蔵されているようになりました。
Name[] applicants = new Name[4];
applicants[0] = new Name("john", "bob", "rush");
applicants[1] = new Name("joe", "bob", "rushden");
applicants[2] = new Name("jack", "bob", "rushden");
applicants[3] = new Name("jake", "bob", "rushden");
Optional<Name> result = Arrays.stream(applicants)
.filter(name -> name.middlename.equals("bob") && name.surname.equals("rush"))
.findAny();
result.ifPresent(name -> System.out.println(name));
ここで使用可能なオプションがたくさんあります。あなたは.findAny()
に.findFirst()
を切り替えることで一致し、あるいは、例えば、.parallel()
後.stream(applicants)
を挿入することにより、並行して、検索を実行するための最初の名前を取得することができます。