如何在Java的通用方法中比较数组?

时间:2018-11-02 10:22:59

标签: java arrays generics

我有一个在其构造函数中使用两个泛型参数的类。我想实现一个方法来比较该类的两个实例,如下面的代码所示。

它工作得很好,除了其中一个参数是数组时。我已经阅读了有关如何使用java.util.Arrays.equals(Object[] a, Object[] a2)比较数组的不同主题,但是由于我的参数未定义为数组,因此无法使用此方法。

在数组内容相同的情况下如何返回“ true”?还是可以强制转换参数以使用java.util.Arrays.equals(Object[] a, Object[] a2)

public class Pair<U, V> {

    public final U first;
    public final V second;

    public Pair(U first, V second) {
        this.first = first;
        this.second = second;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;

        Pair<?, ?> myPair= (Pair<?, ?>) o;

        if (!first.equals(myPair.first) || !second.equals(myPair.second))
            return false;
        return true;
    }
}

4 个答案:

答案 0 :(得分:0)

您可以这样做:

  • 使用here给出的指导来确定两个对象(此对象和“其他”对象)是否都包含数组。当然,检测实际的成员类型意味着更多的工作。
  • 当字段实际上是数组时,利用Array.equals()编写特定的比较代码。

但请不要误会:使equals()实现正确无误,并可以继承,否则……将是一个重大挑战!

例如:您是否认为一个int数组等于一个Integer值列表(假设这些值实际上都相同)?或嵌套数组呢?

这里的重点是:Java没有数组的深层相等性,而且几乎无法自己覆盖所有可能的情况!

答案 1 :(得分:0)

@Override
public boolean equals(Object o) {
    if (this == o)
        return true;
    if (o == null || getClass() != o.getClass())
        return false;

    Pair<?, ?> myPair = (Pair<?, ?>)o;

    if (first.getClass().isArray() ^ first.getClass().isArray() || second.getClass().isArray() ^ second.getClass().isArray())
        return false;
    return deepEquals(first, myPair.first) && deepEquals(second, myPair.second);
}

private static boolean deepEquals(Object one, Object two) {
    if (one instanceof byte[])
        return Arrays.equals((byte[])one, (byte[])two);
    if (one instanceof char[])
        return Arrays.equals((char[])one, (char[])two);
    if (one instanceof short[])
        return Arrays.equals((short[])one, (short[])two);
    if (one instanceof int[])
        return Arrays.equals((int[])one, (int[])two);
    if (one instanceof long[])
        return Arrays.equals((long[])one, (long[])two);
    if (one instanceof boolean[])
        return Arrays.equals((boolean[])one, (boolean[])two);
    if (one instanceof float[])
        return Arrays.equals((float[])one, (float[])two);
    if (one instanceof double[])
        return Arrays.equals((double[])one, (double[])two);
    if (one instanceof Object[])
        return Arrays.equals((Object[])one, (Object[])two);
    return one.equals(two);
}

答案 2 :(得分:0)

public class Fourth {

    public static void main(String[] args) {

        Integer a[] = {1,2,3,4,5};
        Integer b[] = {1,2,3,4,6,7};

        CompareArrays<Integer, Integer> comp = new CompareArrays<Integer, Integer>(a,b);

        comp.compareArrays();

    }
}

class CompareArrays<One extends Number, Two extends Number> {

    One[] array1;
    Two[] array2;

    CompareArrays(One[] ob1, Two[] ob2){
        array1 = ob1;
        array2 = ob2;
    }

    void compareArrays() {

        if(array1.length != array2.length) {
            System.out.println("Two arrays are not equal");

        }else {

            int flag = 0;

            for (int i = 0; i < array1.length; i++) {


                  if(array1[i] != array2[i]) {
                      flag =1;
                  }
            }

            if(flag == 0) {
                System.out.println("Two arrays are equal");
            }else {
                System.out.println("Two arrays are not equal");
            }

        }
    }
}

答案 3 :(得分:-1)

值得注意的是,我所知道的Java中没有任何集合(对,列表,集合...)对此情况有所让步。例如:

List<Integer[]> one = Arrays.asList(
    new Integer[]{1}, new Integer[]{2}
);
List<Integer[]> two = Arrays.asList(
    new Integer[]{1}, new Integer[]{2}
);
System.out.println(one.equals(two));

输出: false

两个集合的相等性仅应由其元素的相等性决定。除此之外,其他一切只会使您的班级合同越来越模糊。

Java中的数组不覆盖等于。那是已经做出的设计决定。尝试通过修改实现来纠正您必须认为错误的决定,这不是您的工作。

总之,你不会。