java - 如何使用 java 8 流过滤具有两个列表的对象?

标签 java java-8

我需要过滤包含大量对象的列表。对于这些对象中的每一个,我都需要验证是否有任何参数包含其他列表中的单词之一。我已经开发了一种方法来做到这一点,但它花费的时间太长,我想知道是否有更有效的方法来做到这一点。

主要思想可以写成sql以便于理解:

SELECT * FROM PROJECT P WHERE P.NAME LIKE "%JAVA%" OR P.NAME LIKE "%PASCAL%" OR P.PRODUCT LIKE "%JAVA%" OR P.PRODUCT LIKE "%PASCAL% OR. P.ADDRESS LIKE "%JAVA" OR P.ADDRESS LIKE "%PASCAL%";

在Java中我是这样写的:

private List<Projeto> filtraResultado(List<Projeto> projetosAssinados, String[] filtros){
List<Projeto> result = new ArrayList<Projeto>();
for(Projeto p: projetosAssinados) {
    if(existeFiltroBuscadoNosCamposDePesquisa(p.getDsProjeto(), filtros) ||
       existeFiltroBuscadoNosCamposDePesquisa(p.getNomeProjeto(), filtros) ||
       existeFiltroBuscadoNosCamposDePesquisa(p.getSetor(),filtros) ||
       existeFiltroBuscadoNosCamposDePesquisa(p.getUn(), filtros) ||
       existeFiltroBuscadoNosCamposDePesquisa(p.getProcessosModelados(),filtros)||
       existeFiltroBuscadoNosCamposDePesquisa(p.getServicosPrestados(),filtros) ||
       existeFiltroBuscadoNosCamposDePesquisa(p.getTecnologias(),filtros)||
       existeFiltroBuscadoNosCamposDePesquisa(p.getDetalhamento(),filtros)) {
            result.add(p);
    }

}
return result;

public boolean existeFiltroBuscadoNosCamposDePesquisa(String campoPesquisado,String[] filtros ){
if(campoPesquisado == null) {
    return false;
}
for(String f: filtros) {
    if(StringUtils.containsIgnoreCase(campoPesquisado, f.trim())) {
        return true;
    }
}
return false;

最佳答案

可以通过创建 Set<String> 来改进方法的时间复杂度包含过滤器元素。这样,搜索特定元素将是 O(1)而不是 O(n) :

private List<Projeto> filtraResultado(List<Projeto> projetosAssinados, String[] filtros) {
    Set<String> filterSet = Arrays.stream(filtros)
            .map(String::toLowerCase)
            .map(String::trim)
            .collect(Collectors.toSet());

    List<Projeto> result = new ArrayList<Projeto>();

    for (Projeto p : projetosAssinados) {
        boolean contained = Stream.of(p.getDsProjeto(), p.getNomeProjeto(),
                p.getSetor(), p.getUn(), p.getProcessosModelados(), 
                p.getServicosPrestados(), p.getTecnologias(), p.getDetalhamento())
            .filter(Objects::nonNull)
            .map(String::toLowerCase)
            .anyMatch(filterSet::contains);

        if (contained) {
            result.add(p);
        }
    }

    return result;
}

对于大量输入,这应该比您的方法快得多。

关于java - 如何使用 java 8 流过滤具有两个列表的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57501545/

相关文章:

java - 如何显示其他布局?

java - @RequestMapping 在渲染方法中带有 2 个参数

java - 将流 sum() 方法应用于列表的 N 个不同字段,在一次迭代中给出 N 个总和结果

java8 + foreach循环的内部工作

java - 由于 RaceCondtion,使用流迭代 LinkedList 正在改变结果列表

java - 单击 JPanel 中的按钮后键盘控件停止工作?

java - 打印成本的“经验法则”

java - JFreechart 替代方案

java - 如何在spring jdbc模板中制作流式sql?

Java 8 Optional 不能应用于接口(interface)