简体   繁体   中英

How to search elements by criteria in java.Util.List<Type>?

For example:

I got a table like this at UI side:

在此输入图像描述

And this is the list that has all data showed above:

List<MyBean> myList;

Now I want to search by categoryName , languageID or categoryID using a method like this:

private List<MyBean> search(List<MyBean> myList, String columnName, String criteria)

So then I just do the following to get the results that matches my criteria:

1st case: List<Bean> results = this.search(myList, "categoryName", "Dog H");

2nd case: List<Bean> results = this.search(myList, "categoryName", "Dog House");

(At this point results list will return 3 elements in both cases -- according to the above table).


Is it possible to achieve this? As you guys can see, this is a kind of search similar to the %LIKE% function from SQL but focused on java.util.List

Thanks in advance.

I solved my question using the following:

Then I just imported the following namespace by this way:

import static ch.lambdaj.Lambda.*;

And get results from my criteria using this:

List<MyBean> results = select(myList, having(on(MyBean.class).getCategoryName(), org.hamcrest.Matchers.containsString("Dog H")));

So, in that line of code I am passing myList , the "column" and criteria as I required in my question.

The rest of code at that line is easy to understand so I won't write about it.

Hope this helps someone else too.

Here's two approaches

The "forceful" approach ;)

public List<MyBean> search(List<MyBean> lstBeans, String method, String regExp) {
    List<MyBean> lstMatch = new ArrayList<>(lstBeans.size());
    Pattern pattern = Pattern.compile(regExp);
    for (MyBean bean : lstBeans) {

        if (method.equals("categoryName")) {
            String name = bean.getCategoryName();
            if (pattern.matcher(name).matches()) {
                lstMatch.add(bean);
            }
        }
    }
    return lstMatch;
}

.
.
.

List<MyBean> matches = search(lstBeans, "categoryName", "^Dog.*$");

Basically, this relies on knowing that a given method name will return a given result, this would make it difficult to filter results on category, for example...

There are also problems with people misspelling the method name or not taking into account that it's case sensitive...

OR you could try something a little more variable

public interface Criteria<T> {
    public boolean matches(T bean);
}

public class CategoryNameCriteria implements Criteria<MyBean> {

    private Pattern pattern;

    public CategoryCriteria(String criteria) {
        pattern = Pattern.compile(criteria);
    }

    @Override
    public boolean matches(MyBean bean) {
        return pattern.matcher(bean.getCategoryName()).matches();
    }

}

public <T> List<T> search(List<T> lstBeans, Criteria<T> critera) {
    List<T> lstMatch = new ArrayList<>(lstBeans.size());
    for (T bean : lstBeans) {
        if (critera.matches(bean)) {
            lstMatch.add(bean);
        }
    }
    return lstMatch;
}

.
.
.

matches = search(lstBeans, new CategoryNameCriteria("^Dog.*$"));

This would allow you to "define" your own criteria and matching requirements without changing the basic method

This would mean you could to develop up a series of criteria independent of the search method, such as

public class CategoryIDCriteria implements Criteria<MyBean> {

    private int id;

    public CategoryIDCriteria(int id) {
        this.id = id;
    }

    @Override
    public boolean matches(MyBean bean) {
        return bean.getCategoryID() == id;
    }

}

.
.
.

matches = search(lstBeans, new CategoryIDCriteria(1));

And because the criteria and search method are generic, it would be possible to reuse it with different types of objects

If you are willing to use third party libraries, perhaps JoSQL will suffice? It allows you to filter collections of POJOs using SQL queries...

Also, if you are willing to move away from SQL queries, this old post may be of interest: How do you query object collections in Java (Criteria/SQL-like)?

Instead of a List, why not use Guava's Table ?

Table<Integer, Integer, String> table = HashBasedTable.create(); 
table.put(1, 1, "Advantage Flea");
table.put(1, 2, "Advantage Flea");
table.put(1, 3, "Advantage Flea");
.
.
.

Case #1 requires something like:

Collection<String> values = table.values();
for(String value : values) { 
   if(value.contains(queryString) { 
       //found it!
   }
}

Case #2 is trivial, and just looks like:

if(table.containsValue("Advantage Flea") { 
    ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM