java - 使用谓词动态过滤列表

标签 java guava predicate

我有以下字符串列表:

{"New York","London","Paris","Berlin","New York"}

我正在尝试使用 Guava 库,并且我想以这样的方式过滤此列表,以便仅获得与我将提供的字符串相等的字符串。如果我有一个固定值,比如说“纽约”,我会执行以下操作:

Predicate<String> myCity = new Predicate<String>() {
    @Override public boolean apply(String city) {
        return city == "New York";
    }               
};

但是如果我希望 return 语句是这样的:

return city == myStringVariable

我可以将城市的参数赋予谓词或以某种方式组合两个谓词吗?

最佳答案

Guava 通过Predicates 提供了许多真正通用的谓词。辅助类。

要过滤相等性(无论是 String 还是任何其他对象),它提供 equalTo()谓词:

Predicate<String> myCity = Predicates.equalTo(myStringVariable);
<小时/>

更新以回答评论中的问题:当列表不是 String 而是具有 String 属性的对象时,如何进行过滤。

您有多种选择,具体取决于您已有的内容:

  1. 使用命令式代码

    对于一次性使用,除非您使用 Java 8,否则使用函数构造有点冗长。请参阅FunctionalExplained维基页面。

    private List<SomeObject> filterOnMyCity(List<SomeObject> list,
                                            String value) {
        List<SomeObject> result = new ArrayList<>();
        for (SomeObject o : list) {
            if (value.equals(o.getMyCity())) {
                result.add(o);
            }
        }
        return result;
    }
    
  2. 使用临时谓词

    class MyCityPredicate implements Predicate<SomeObject> {
         private final String value;
    
         public MyCityPredicate(String value) {
             this.value = value;
         }
    
         @Override
         public boolean apply(@Nullable SomeObject input) {
             return input != null && value.equals(input.getPropertyX());
         }
    }
    
    return FluentIterable.from(list)
            .filter(new MyCityPredicate(myStringVariable))
            .toList();
    
  3. 使用现有函数

    class MyCityFunction implements Function<SomeObject, String> {
         @Override
         public String apply(@Nullable SomeObject input) {
             return input == null ? null : input.getPropertyX();
         }
    }
    
    return FluentIterable.from(list)
            .filter(Predicates.compose(
                    Predicates.equalTo(myStringVariable),
                    new MyCityFunction()))
            .toList();
    

但是,我不会重写评论中提到的 equals(),它可能过于具体,不能仅仅因为一个 SomeObject 实例就相等他们的属性是。如果您需要在不同上下文中过滤 2 个不同的属性,它不会扩展。

如果您使用 Java 8,则使用 lambda 表达式,代码会变得更加紧凑,并且无论如何您都可以直接使用 Stream API,因此您不需要 Guava >.

关于java - 使用谓词动态过滤列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24454212/

相关文章:

java - map 列表 : efficient implementations

java - 使用Guava的ComparisonChain比较包含罗马数字的字符串

list - Lisp - 如何检查列表是否为点对?

Java 8 - 如何使用具有参数函数的谓词?

java - 创建 LDAP 领域时出现 Glassfish 错误 : "Invalid property syntax, "="in value

Java占位符: reference to webapp folder

java - 实现类的实例

java - 找到匹配的谓词。谓词的谓词?

c# - 通用查询方法

java - 如何将二进制与枚举一起使用?