简体   繁体   English

如何按java.Util.List中的条件搜索元素 <Type> ?

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

For example: 例如:

I got a table like this at UI side: 我在UI端有一个这样的表:

在此输入图像描述

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: 现在我想使用类似这样的方法按categoryNamelanguageIDcategoryID进行搜索:

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"); 第一种情况: List<Bean> results = this.search(myList, "categoryName", "Dog H");

2nd case: List<Bean> results = this.search(myList, "categoryName", "Dog House"); List<Bean> results = this.search(myList, "categoryName", "Dog House"); 情况: 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). (此时results列表将在两种情况下返回3个元素 - 根据上表)。


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 正如大家们所看到的,这是一种类似于SQL%LIKE%函数的搜索,但主要关注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. 所以,在那行代码中,我传递myList"column"我的问题"column"所要求的"column"criteria

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? 如果你愿意使用第三方库,也许JoSQL就足够了? It allows you to filter collections of POJOs using SQL queries... 它允许您使用SQL查询过滤POJO集合...

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)? 此外,如果您愿意放弃SQL查询,可能会对此旧帖子感兴趣: 如何在Java中查询对象集合(Criteria / SQL-like)?

Instead of a List, why not use Guava's Table ? 而不是List,为什么不使用Guava的

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: 案例#1需要以下内容:

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

Case #2 is trivial, and just looks like: 案例#2是微不足道的,看起来像:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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