Java 通用对象数值比较方法

前言

请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i


提示:以下是本篇文章正文内容,下面案例可供参考

说明

主要用于比较两个对象是否相等,特别处理了数值类型的比较(包括字符串形式的数值)

  • 数值比较的精度处理:
    通过 BigDecimal 比较字符串或数字,避免 == 或 equals 的精度问题(如 0.200 vs 0.2)。
  • 类型覆盖全面:
    支持 String、Number、Character 等常见类型,其他类型回退到 equals。
  • 健壮性:
    对非法数值字符串(如 “abc”)或不支持的类型会记录警告并返回 false。
/**
     * .
     * 基本数据类型比对
     *
     * @param obj1 内容1
     * @param obj2 内容2
     * @return 结果
     */
    private static boolean areEqual(Object obj1, Object obj2) {
        if (obj1 == null && obj2 == null) {
            return true;
        }
        if (obj1 == null || obj2 == null) {
            return false;
        }

        // 尝试将对象转换为BigDecimal进行比较
        BigDecimal bd1 = tryConvertToBigDecimal(obj1);
        BigDecimal bd2 = tryConvertToBigDecimal(obj2);

        if (bd1 != null && bd2 != null) {
            return bd1.compareTo(bd2) == 0;
        }

        // 如果无法转换为数字,使用默认的equals比较
        return obj1.equals(obj2);
    }

    /**
     * .
     * 尝试将各种类型转换为BigDecimal
     *
     * @param obj 数值
     * @return
     */
    private static BigDecimal tryConvertToBigDecimal(Object obj) {
        if (obj instanceof Number) {
            return convertToBigDecimal((Number) obj);
        } else if (obj instanceof String) {
            try {
                return new BigDecimal((String) obj);
            } catch (NumberFormatException e) {
                log.warn("[{}]:不是有效的数字字符串", obj);
                return null;
            }
        } else if (obj instanceof Character) {
            return new BigDecimal((Character) obj);
        }
        log.warn("[{}]:不支持的类型", obj);
        return null;
    }

    /**
     * .
     * 安全转换Number为BigDecimal
     *
     * @param number
     * @return
     */
    private static BigDecimal convertToBigDecimal(Number number) {
        if (number instanceof BigDecimal) {
            return (BigDecimal) number;
        } else if (number instanceof Double || number instanceof Float) {
            return new BigDecimal(number.toString());
        } else {
            return BigDecimal.valueOf(number.longValue());
        }
    }

    public static void main(String[] args) {
        Map<String, Object> rcXmlMap = new ConcurrentHashMap<>();
        Map<String, Object> blzXmlMap = new ConcurrentHashMap<>();
        rcXmlMap.put("fieldKey", "0.200");
        blzXmlMap.put("fieldKey", "0.2");
        rcXmlMap.put("a", "64");
        blzXmlMap.put("a", "64");
        rcXmlMap.put("b", "你");
        blzXmlMap.put("b", "你");
        Object rcValue = rcXmlMap.get("fieldKey");
        Object blazeValue = blzXmlMap.get("fieldKey");
        System.out.println(areEqual(rcValue, blazeValue));

        rcValue = rcXmlMap.get("a");
        blazeValue = blzXmlMap.get("a");
        System.out.println(areEqual(rcValue, blazeValue));


        rcValue = rcXmlMap.get("b");
        blazeValue = blzXmlMap.get("b");
        System.out.println(areEqual(rcValue, blazeValue));
    }

运行结果:

true
true
 WARN - [main] c.e.c.t.process.BasicProcess:[108] - []:不是有效的数字字符串
 WARN - [main] c.e.c.t.process.BasicProcess:[108] - []:不是有效的数字字符串
true

总结

我是南国以南i记录点滴每天成长一点点,学习是永无止境的!转载请附原文链接!!!

### Java中不同数值类型比较大小的方式及实现方法Java中,数值类型的大小比较主要分为基本数据类型和包装类两种情况。对于基本数据类型(如`int`、`double`、`float`等),可以直接使用关系运算符进行比较,例如`>`、`<`、`==`等。然而,由于浮点数的精度问题,在比较`float`和`double`时需要特别注意误差范围。 #### 基本数据类型的比较 - 对于整型数据(如`byte`、`short`、`int`、`long`),可以直接使用`==`、`!=`、`>`、`>=`、`<`、`<=`等操作符来判断两个值是否相等或者一个值是否大于另一个值。 - 浮点型数据(如`float`、`double`)由于存在精度丢失的问题,不建议直接使用`==`或`!=`来进行相等性检查。通常的做法是计算两个浮点数之间的差值,并与一个小量(epsilon)做比较以确定它们是否足够接近从而被认为是相等的[^2]。 ```java double a = 0.1 + 0.2; double b = 0.3; boolean isEqual = Math.abs(a - b) < 1e-9; // 使用一个小量作为容差 ``` #### 包装类的比较 当涉及到数值的包装类(如`Integer`、`Double`)时,可以利用它们实现了`Comparable<T>`接口这一特性,通过调用`compareTo()`方法来进行比较。此外,也可以将对象转换为基本类型后进行比较。 ```java Double d1 = 3.14; Double d2 = 2.71; int result = d1.compareTo(d2); // 返回正数表示d1>d2, 负数表示d1<d2, 0表示相等 ``` #### 泛型数值比较 如果希望编写能够处理多种数值类型的通用代码,则可以通过泛型配合类型转换来实现。例如,可以创建一个方法接受`Number`类型的参数,并将其转换为适当的数值类型进行比较[^3]。 ```java public <T extends Number> int compareNumbers(T num1, T num2) { double n1 = num1.doubleValue(); double n2 = num2.doubleValue(); if (Math.abs(n1 - n2) < 1e-9) return 0; else if (n1 > n2) return 1; else return -1; } ``` #### 表达式引擎比较 有时可能需要根据表达式字符串动态地执行数值比较。这时可以考虑使用`ScriptEngine`,它允许解析并执行JavaScript或其他脚本语言中的条件表达式来完成复杂的逻辑判断[^4]。 ```java ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("JavaScript"); try { boolean result = (Boolean)engine.eval("5 >= 0"); } catch (ScriptException e) { e.printStackTrace(); } ``` #### 特殊情况处理 - 当比较包含不确定精度的浮点数时,推荐采用绝对误差或相对误差的方法来判定两数是否“近似”相等[^5]。 - 如果要确保跨平台的一致性,尤其是涉及金融计算等场景下,应使用`BigDecimal`类提供的精确算术运算功能来进行比较。 综上所述,Java提供了多种方式用于数值类型的大小比较开发者可以根据具体需求选择合适的方法。对于简单的整数比较,直接使用关系运算符即可;而对于浮点数则需谨慎处理其精度问题;若需支持多种数值类型或是更复杂的比较逻辑,则可借助泛型编程或脚本引擎等高级特性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南国以南i

你的鼓励将是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值