Java:比较具有相同值的两个不同类型的对象,返回 true

标签 java object compare

我有一些数据需要比较。我可能必须比较不同数据类型的值。这是基本上发生的事情:

Object a = (long) 1;
Object b = (int) 1;


System.out.println(Objects.equals(a, b)); //returns false

Sysout.out.println(Objects.equals(a.toString(), b.toString())); //returns true

使用 .toString() 似乎是一个可行的解决方案吗?还是我应该走另一条路?

编辑:

这个程序正在从 HIVE 表中读取,其中一些表可能包含完全相同的数据,但数据类型不同。数据类型包括 int、smallint、bigint、string、array、double、timestamp。

我不关心数组比较,因为除了数组类型之外没有什么可以容纳数组。但是,可以将 String 类型与时间戳进行比较。我也不关心 int 到 double 的比较,因为这些应该会导致 false。

任何没有小数位和不同数据类型的数值都应该与其值进行比较,数据类型不匹配不应返回 false。

编辑:

任何带小数的数字在比较前都会四舍五入到小数点后 3 位。

最佳答案

这里有一种方法可以准确地进行已编辑问题中描述的比较。

/**
 * Compare objects for equal value, with some disregard for type.
 * <p>
 * The following types are considered similar, for the purpose of comparing values. The
 * values of the secondary types are converted to the first listed type for value comparison.
 * <ul>
 * <li>{@code long}, {@code int}, {@code short}</li>
 * <li>{@code double} <i>(rounded to 3 decimals before comparing)</i></li>
 * <li>{@code String}, {@code Timestamp}</li>
 * <li>Array <i>(elements are compared using this method, comparison is "deep")</i></li>
 * </ul>
 * Values for all other types are only considered equal if they have the exact same type
 * and {@code equals()} return {@code true}.
 * 
 * @param obj1 the first object to be compared.
 * @param obj2 the second object to be compared.
 * @return {@code true} only if the specified objects are equals according to the rules listed above.
 */
public static boolean equalValue(Object obj1, Object obj2) {
    // Compare null values
    if (obj1 == null)
        return (obj2 == null);
    if (obj2 == null)
        return false;

    Class<?> class1 = obj1.getClass();
    Class<?> class2 = obj2.getClass();

    // Compare double values, rounded to 3 decimal places
    if (class1 == Double.class && class2 == Double.class) {
        // Can't use Math.round() because it doesn't do round-half-up, and may overflow long value-range
        BigDecimal dec1 = BigDecimal.valueOf(((Number)obj1).doubleValue()).setScale(3, RoundingMode.HALF_UP);
        BigDecimal dec2 = BigDecimal.valueOf(((Number)obj2).doubleValue()).setScale(3, RoundingMode.HALF_UP);
        return dec1.equals(dec2); // equals() is ok, since we know they have same scale
    }

    // Compare arrays
    if (class1.isArray() && class2.isArray()) {
        int len = Array.getLength(obj1);
        if (len != Array.getLength(obj2))
            return false;
        for (int i = 0; i < len; i++)
            if (! equalValue(Array.get(obj1, i), Array.get(obj2, i)))
                return false;
        return true;
    }

    // Now that special cases are done, apply simple comparison for values of same type
    if (class1 == class2)
        return obj1.equals(obj2);

    // Compare long/int/short values
    if ((class1 == Long.class || class1 == Integer.class || class1 == Short.class) &&
        (class2 == Long.class || class2 == Integer.class || class2 == Short.class)) {
        return ((Number)obj1).longValue() == ((Number)obj2).longValue();
    }

    // Compare String/Timestamp values
    if ((class1 == String.class || obj1 instanceof Timestamp) &&
        (class2 == String.class || obj2 instanceof Timestamp)) {
        return obj1.toString().equals(obj2.toString());
    }

    return false; // Incomparable types
}

关于Java:比较具有相同值的两个不同类型的对象,返回 true,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38253495/

相关文章:

python - 比较 Python 中可变数量的非关键字参数

java - Java中唯一标识文件

Javascript 循环通过 JSON 对象数组

javascript - 比较对象数组,最佳方式

java - 查找 1 个字符串中的每个字符是否存在于另一个字符串中,比 O(n^2) 更快

javascript - 如何获取每个对象键的 id

java - 在 EAR 的 APP-INF/lib 中加载 JAR 的顺序

java - 如何让我的应用程序出现在第二台显示器的中央,而不是主显示器的中央?

java - 在 JEditorPane 中设置内联文本和图像

javascript - 使用 reduce 构建数组对象比较两个数组