Take the 2-minute tour ×

I want to implement search on property of objects which are in list.

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

Input param:

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

I want to go with Collections.binarySearch but how to make dynamic comparator search that I don't know.

what is right way to implement such function?

Is it possible to implement it using Collections.binarySearch or any other good way with good quality of code with better performance?


List<Test> finalSearch=new ArrayList<Test>();
//Write code to search data
for(Test test:testList)
///Same code for others
share|improve this question
First write a search using a plain old loop. Then study what you wrote and figure out what parts comprise the comparator. –  Hot Licks Oct 2 '13 at 11:19
Can you elaborate more? you mean looping the list and according to property compare search value. is it? –  NFE Oct 2 '13 at 11:25
So you know that you need to use a Comparator, but don't know how to use it? Why don't you learn? –  Rafi Kamal Oct 2 '13 at 11:26
As there are three fields, you can't simply use binarySearch. To use binarySearch the list must be sorted. You can't sort a list on three fields. –  Rafi Kamal Oct 2 '13 at 11:29
I edited my code. is this correct approach? It is just a sample actually I have 25 property in bean. –  NFE Oct 2 '13 at 11:31

2 Answers 2

I doubt you can do a bin-search with this problem. If you want to do a binary search, your elements in the collection must be sorted by the given propertyName. If it is not, you have to sort it first (with comparator for example). So you are changing a O(n) problem to O(nlgn).

what I can think of is: java reflection API.... That is, in your searchData method, build the getter method (java.lang.reflect.Method) by the given property name. And invoke (method.invoke() http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Method.html#invoke(java.lang.Object, java.lang.Object...) ) to get the property value. And do the filtering.

You can implement it by yourself, if you don't mind to use libraries, you could take a look apache beanUtils: (getProperty() method)

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)

also the Iterables.filter() method from guava:

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

share|improve this answer

As others said, you can't use binary search without sorting the list first, so I will not take that into account.

I have an elegant solution to this problem using Google's Guava libraries and without resorting to reflection.

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>() {
        public boolean apply(T input) {
            return value.equals(function.apply(input));

This function takes three parameters.

  1. The list you want to filter.
  2. A function which takes an element of the list, and returns the value of the property you want to filter on
  3. The value you want the property to have

In order to use it before Java 8, you can write something like this:

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>() {
        public Integer apply(Test input) {
            return input.id;
    public static final Function<Test, String> GetName = new Function<Test, String>() {
        public String apply(Test input) {
            return input.name;


Once you have Test.GetId, Test.GetName etc defined, using filter is easy and clear:

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");
share|improve this answer
OP has a big block of "if this property, call getThisProperty() else if that property..." Your approach is just moving this block into the bean class right? if doing so, a Map<String, Object> is enough. e.g. PropertyMap<String, Object> map then map.put("name",this.name);..... –  Kent Oct 2 '13 at 13:16
Ok but with this approach you don't have to create a map for every object, just for the sake of searching. I'd rather go with reflection if there are many classes with different properties. Or use something like Lambdaj. –  Flavio Oct 2 '13 at 14:45
the map would be in the bean class. I wrote THIS.name –  Kent Oct 2 '13 at 15:00

Your Answer


