You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现可比较同类型任意Number的泛型Lambda比较器

核心实现思路

所有Java数值包装类(Integer、Double、Long等)都实现了Comparable接口,你可以基于compareTo方法实现通用比较逻辑,不需要重复为每个类型编写实现,也可以完全规避额外运行时开销,同时保留lambda的高性能特性。


第一步:优化基础接口

调整Operator接口的泛型限定和返回值,更适配比较操作的场景:

// 泛型限定为实现了Comparable的类型,所有数值包装类都满足该要求
public interface Operator<T extends Comparable<T>> {
    boolean eval(T p1, T p2);
}

第二步:实现通用比较运算符

不需要单独为每个数值类型编写静态方法,直接通过泛型方法生成对应类型的运算符即可:

public class ComparisonOperators {
    // 大于等于
    public static <T extends Comparable<T>> Operator<T> greaterOrEqual() {
        return (v1, v2) -> v1.compareTo(v2) >= 0;
    }

    // 小于等于
    public static <T extends Comparable<T>> Operator<T> lessOrEqual() {
        return (v1, v2) -> v1.compareTo(v2) <= 0;
    }

    // 等于
    public static <T extends Comparable<T>> Operator<T> equal() {
        return (v1, v2) -> v1.compareTo(v2) == 0;
    }

    // 大于
    public static <T extends Comparable<T>> Operator<T> greaterThan() {
        return (v1, v2) -> v1.compareTo(v2) > 0;
    }

    // 小于
    public static <T extends Comparable<T>> Operator<T> lessThan() {
        return (v1, v2) -> v1.compareTo(v2) < 0;
    }
}

第三步:消除冗余的instanceof判断

通过工厂类提前缓存常用数值类型的运算符实例,运行时直接根据值的类型获取对应运算符即可:

public class OperatorFactory {
    // 缓存常用类型的大于等于运算符实例,其他运算符可按相同逻辑扩展缓存
    private static final Map<Class<?>, Operator<? extends Comparable<?>>> GE_CACHE = new HashMap<>();

    static {
        GE_CACHE.put(Integer.class, ComparisonOperators.<Integer>greaterOrEqual());
        GE_CACHE.put(Double.class, ComparisonOperators.<Double>greaterOrEqual());
        GE_CACHE.put(Long.class, ComparisonOperators.<Long>greaterOrEqual());
        GE_CACHE.put(Short.class, ComparisonOperators.<Short>greaterOrEqual());
        GE_CACHE.put(Float.class, ComparisonOperators.<Float>greaterOrEqual());
        GE_CACHE.put(Byte.class, ComparisonOperators.<Byte>greaterOrEqual());
    }

    @SuppressWarnings("unchecked")
    public static <T extends Comparable<T>> Operator<T> getGreaterOrEqual(Class<T> type) {
        return (Operator<T>) GE_CACHE.get(type);
    }

    // 其他运算符的工厂方法可按相同逻辑扩展
}

原来GUI中的冗余判断代码可以直接简化为一行:

Expression.setOperator(OperatorFactory.getGreaterOrEqual(Param.value.getClass()));

性能说明

该实现完全基于lambda和Comparable的原生实现,无反射开销,和单独为每个类型编写的lambda性能完全一致。每个类型的Operator实例都是提前创建的,运行时直接调用compareTo方法会被JVM自动内联优化,性能和直接使用>=等运算符几乎无差异。

内容的提问来源于stack exchange,提问作者MicD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 02:57:00