当前位置: 首页 > 知识库问答 >
问题:

如果过滤条件是多个且动态出现,则从List中过滤对象

孟泽宇
2023-03-14

我有一个要求,我必须根据多个动态过滤条件从列表中过滤对象。

我已经通过在对象上循环编写了代码,然后使用所有过滤器,如果任何条件不匹配,则返回false。我编写的代码如下:

    Map<String, String> obj1  = new HashMap<>();
    obj1.put("id", "1");
    obj1.put("name", "name1");
    obj1.put("dept", "IT");
    obj1.put("sex", "M");

    Map<String, String> obj2  = new HashMap<>();
    obj2.put("id", "2");
    obj2.put("name", "name2");
    obj2.put("dept", "IT");
    obj2.put("sex", "M");

    Map<String, String> obj3 = new HashMap<>();
    obj3.put("id", "3");
    obj3.put("name", "name3");
    obj3.put("dept", "DEV");
    obj3.put("sex", "F");

    ArrayList<Map<String, String>> employees = new ArrayList<>(Arrays.asList(obj1,obj2,obj3));

    Map<String, String> filterCondition = new HashMap<>();
    filterCondition.put("dept", "IT");
    filterCondition.put("sex", "M");

    List<Map<String, String>> filteredEmployee = new ArrayList<>();

    for(Map<String,String> employee:employees){
        if(isValid(filterCondition, employee)){
            filteredEmployee.add(employee);
        }
    }

    System.out.println(filteredEmployee);

是验证方法

private static boolean isValid(Map<String, String> filterCondition, Map<String, String> employee) {
    for(Entry<String, String> filterEntry:filterCondition.entrySet()){
        if(!employee.get(filterEntry.getKey()).equals(filterEntry.getValue())){
            return false;
        }
    }
    return true;
}

如果我得到的过滤器是动态的,有没有更好的方法来实现呢?

我已经在stackoverflow中看到了一些答案,但没有任何帮助

共有2个答案

马淇
2023-03-14

也许您可以将 for 循环与流一起使用:

    Stream<Map<String, String>> employeeStream = employees.stream();
    for (Map.Entry<String, String> entry : filterCondition.entrySet()) {
        employeeStream = employeeStream.filter(map -> entry.getValue()
                                          .equals(map.get(entry.getKey())));
    }
    List<Map<String, String>> filteredEmployee = employeeStream.collect(Collectors.toList());
胡泓
2023-03-14

将所有过滤器合并为一个谓词(使用流、减少和谓词组合):

Predicate<Map<String, String>> allConditions = filterCondition
        .entrySet()
        .stream()
        .map(ThisClass::getAsPredicate)
        .reduce((employee) -> true, Predicate::and);

然后只需使用Stream.filter()

List<Map<String, String>> filteredEmployees = employees
        .stream()
        .filter(allConditions)
        .collect(Collectors.toList());

辅助功能:

private static Predicate<Map<String, String>> getAsPredicate(Map.Entry<String, String> filter) {
    return (Map<String, String> employee) -> employee.get(filter.getKey()).equals(filter.getValue());
}
 类似资料:
  • 问题内容: 我正在尝试使用Pandas在几个条件下进行布尔索引。我原来的DataFrame称为。如果执行以下操作,将得到预期的结果: 但是,如果我这样做(我认为应该是等效的),则不会返回任何行: 知道导致差异的原因是什么? 问题答案: 使用是因为运算符优先级: 或者,在单独的行上创建条件: 样品 :

  • 问题内容: 我有一个像这样的数组: 现在,我想按某种条件过滤该数组,只保留值等于2的元素,并删除值不等于2的所有元素。 所以我的预期结果数组将是: 注意:我想保留原始数组中的键。 如何使用PHP做到这一点?有内置功能吗? 问题答案:

  • 问题内容: 我刚刚开始使用SQLAlchemy。我决定使用它,因为我在sqlite查询中间使用了很多字符串表达式。 所以,这就是我的问题。我的桌子上有很多设备,每个设备都有维护级别的日期。关键是用户可以选择他想在屏幕上看到的维护级别。因此,我应该为他选择的每种维护级别组合“调整”我的SQLAlchemmy。 例如,在原始SQLite中。 SELECT * WHERE(设备IN [])和m_leve

  • 问题内容: 我想像这样做一个ElasticSearch查询: 我试图像这样在NEST中实现它: 但这给了我这样的查询,其中的过滤器包装在 布尔值中 : 我应该如何更改我的NEST代码以提供正确的查询?是否必须将我的条款添加到 QueryContainer之外的 其他项目中? 问题答案: 如果要检查条件过滤器,可以在查询之前创建过滤器列表,如下所示: 如果在进行过滤器查询之前不需要检查任何条件,则可

  • 我们嵌套了几个实体。但是在检索时,我们只想获取那些活动的实体。 请求我只想获取处于活动状态的属性( = 1)。 搜索了一下,我发现了一些Hibernate注释和使用子查询的可能性。然而,这两种都不适合我。尽管我们目前正在使用Hibernate,但我正在考虑用Eclipselink替换它,因为我们目前必须使用急切加载,我们可能会遇到性能问题。子查询实际上效果不好,因为我们嵌套了几个级别。 Eclip

  • 我试图创建一个函数,该函数接受多个谓词条件,并根据这些条件过滤流。我找不到任何东西,但我的retList似乎只是由输入组成,而不是输入的过滤版本。 以下是给我的指示: //要生成一个整数流,并将其设置为每个谓词p的输入,请将此流变量设置为对流应用过滤器(p)的结果。完成for-each循环后,像我们在前面的问题中所做的那样,将结果流收集到一个列表中,返回结果列表 这是我目前拥有的: 这就是它的测试