0

リストにあるオブジェクトのプロパティで検索を実装したい。

class Test
{
    int id;
    int name;
    int address;

    //Setter and getter method of properties
}

public List<Test> searchData(String serachText, String propertyName)
{
    //Write code to search data from list
}

入力パラメータ:

searchData("val1", "name");
searchData("val2", ("address");

行きたいCollections.binarySearchけどどうやってdynamic comparator検索したらいいのかわからない。

そのような機能を実装する正しい方法は何ですか?

それを使用して実装することは可能ですCollections.binarySearchか、または他の良い方法でコードの品質を向上させ、パフォーマンスを向上させることはできますか?

編集

public List<Test> searchData(String serachText, String propertyName)
{
List<Test> finalSearch=new ArrayList<Test>();
//Write code to search data
for(Test test:testList)
{
  if(propertyName.equals("name"))
{
    if(serachText.equals(test.getName())
    {
       finalSearch.add(test);
     }
///Same code for others
}
}
}
4

2 に答える 2

0

他の人が言ったように、最初にリストをソートしないとバイナリ検索を使用できないため、それは考慮しません。

Google のGuava ライブラリを使用し、リフレクションに頼らずに、この問題に対するエレガントな解決策があります。

public static <T, V> Collection<T> filter(List<T> source, final Function<? super T, V> function, final V value) {
    return Collections2.filter(source, new Predicate<T>() {
        @Override
        public boolean apply(T input) {
            return value.equals(function.apply(input));
        }
    });
}

この関数は 3 つのパラメーターを取ります。

  1. フィルタリングするリスト。
  2. リストの要素を受け取り、フィルタリングするプロパティの値を返す関数
  3. プロパティに持たせたい値

Java 8 より前で使用するには、次のように記述します。

static class Test {
    int id;
    String name;
    String address;

    public Test(int id, String name, String address) {
        this.id = id;
        this.name = name;
        this.address = address;
    }

    //Setter and getter method of properties...

    public static final Function<Test, Integer> GetId = new Function<Test, Integer>() {
        @Override
        public Integer apply(Test input) {
            return input.id;
        }
    };
    public static final Function<Test, String> GetName = new Function<Test, String>() {
        @Override
        public String apply(Test input) {
            return input.name;
        }
    };

}

などを定義したらTest.GetIdTest.GetName使用filterは簡単で明確です。

public static void main(String[] args) {
    List<Test> t = Arrays.asList(new Test(1, "A", "B"), new Test(2, "C", "D"));
    Collection<Test> f1 = filter(t, Test.GetId, 2);
    Collection<Test> f2 = filter(t, Test.GetName, "A");
}
于 2013-10-02T13:05:07.150 に答える
0

この問題でビン検索を実行できるとは思えません。二分検索を実行する場合は、コレクション内の要素を指定された propertyName で並べ替える必要があります。そうでない場合は、最初に並べ替える必要があります(たとえば、コンパレーターを使用)。したがって、O(n)問題を に変更していO(nlgn)ます。

私が考えることができるのは、次のとおりです。JavaリフレクションAPI ....つまり、searchDataメソッドで、指定されたプロパティ名でゲッターメソッド(java.lang.reflect.Method)を構築します。method.invoke() そして、( http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Method.html#invoke(java.lang.Object , java.lang.Object...) )を呼び出しますプロパティ値を取得します。そしてフィルタリングを行います。

ライブラリを使用することを気にしない場合は、自分で実装できます。apache beanUtils: (getProperty() メソッド) を参照してください。

http://commons.apache.org/proper/commons-beanutils/javadocs/v1.8.3/apidocs/org/apache/commons/beanutils/PropertyUtilsBean.html#getProperty(java.lang.Object , java.lang.String)

また、Iterables.filter()グアバからの方法:

http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/collect/Iterables.html#filter(java.lang.Iterable , com.google.common.base.述語)

于 2013-10-02T12:49:37.497 に答える