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.
Hamcrest (hamcrest-all-1.3.jar) -- http://hamcrest.googlecode.com/files/hamcrest-all-1.3.jar
Lambdaj (lambdaj-2.4-with-dependencies.jar) -- http://lambdaj.googlecode.com/files/lambdaj-2.4-with-dependencies.jar
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.