You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何按类型动态创建泛型Lambda实现?附Predicate场景需求

通用相等判断Predicate实现方案

没问题!这其实是个很典型的通用谓词场景,我们可以用Java泛型实现一个可复用的工具方法,返回Predicate<T>,而且不管什么类都能兼容——只要你的类正确实现了equals()方法就行。

核心思路

所有Java类都继承自Object,而equals()是判断对象相等性的核心方法。我们可以基于这个方法,结合泛型写出一个通用的Predicate生成器,同时处理null的情况避免空指针异常。

代码实现

先写一个工具类,里面放这个通用方法:

import java.util.function.Predicate;

public class PredicateUtils {
    // 生成判断对象相等的Predicate,支持所有类型,处理null场景
    public static <T> Predicate<T> equalsTo(T target) {
        // 先判断目标是否为null,避免调用equals时触发NPE
        return candidate -> target == null ? candidate == null : target.equals(candidate);
    }
}

使用示例

1. 自定义类的场景

先定义一个自定义类,记得正确重写equals()hashCode()(这是Java规范里的好习惯,equals和hashCode要成对重写):

import java.util.Objects;

class Product {
    private String sku;
    private String name;

    // 构造器
    public Product(String sku, String name) {
        this.sku = sku;
        this.name = name;
    }

    // getter省略

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Product product = (Product) o;
        return Objects.equals(sku, product.sku) && Objects.equals(name, product.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(sku, name);
    }
}

然后用这个Predicate来过滤集合:

import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Product> products = Arrays.asList(
            new Product("SKU001", "笔记本"),
            new Product("SKU002", "鼠标"),
            new Product("SKU001", "笔记本")
        );

        // 要匹配的目标对象
        Product target = new Product("SKU001", "笔记本");
        // 用通用方法生成Predicate,过滤集合
        List<Product> matchedProducts = products.stream()
            .filter(PredicateUtils.equalsTo(target))
            .toList();

        // 输出结果:会包含两个SKU001的笔记本
        matchedProducts.forEach(p -> System.out.println(p.getName()));
    }
}

2. JDK自带类的场景

这个方法同样适用于String、Integer这些自带类:

import java.util.Arrays;
import java.util.List;

public class StringExample {
    public static void main(String[] args) {
        List<String> words = Arrays.asList("apple", "banana", "apple", "orange");
        Predicate<String> isApple = PredicateUtils.equalsTo("apple");
        List<String> apples = words.stream().filter(isApple).toList();
        // 结果是["apple", "apple"]
    }
}

关键说明

  • null安全:方法里先判断目标对象是否为null,避免了target.equals(candidate)时的空指针异常,不管目标是null还是候选对象是null都能正确处理。
  • 通用性:泛型<T>让这个方法支持任何类型,只要该类型的equals()逻辑符合你的预期就行。
  • 复用性:把这个方法放在工具类里,整个项目的任何地方都可以直接调用,不用重复写相等判断的逻辑。

内容的提问来源于stack exchange,提问作者Wi-Al

火山引擎 最新活动