Java Array Comparison

前端 未结 6 1847
名媛妹妹
名媛妹妹 2021-01-04 19:48

Working within Java, let\'s say I have two objects that, thanks to obj.getClass().isArray(), I know are both arrays. Let\'s further say that I want to compare

相关标签:
6条回答
  • 2021-01-04 20:13

    you can use the enum strategy pattern to create a comparator for each type:

    public enum ArrayEq {
        BYTE_PRIMITIVE(Byte.TYPE) {
            protected boolean doEquals(Object array1, Object array2) {
                return Arrays.equals((byte[]) array1, (byte[]) array2);
            }
        },
        ... enum element for each component type
    
       private final Class<?> type;
    
       private ArrayEq(final Class<?> type) { this.type = type; }
       public Class<?> getComponentType() { return type; }
    
       // force all enums to implement this method
       protected abstract boolean doEquals(Object array1, Object array2);
    
       public static boolean equals(Object array1, Object array2) {
           if(array1 == null) return array2 == null;
    
           // you need to populate this map in a static initializer of the enum
           // a simple linear search would work too since the number of elements is small
           typeToElementMap.get(array1.getComponentType())
               .doEquals(array1, array2);
       }
    

    }

    Error handling omitted, but of course, you want to throw IllegalArgumentException wherever incorrect types are passed around (I prefer to let ClassCastException be JVM generated, and throw IAE in my own code when I detect something wrong).

    0 讨论(0)
  • 2021-01-04 20:14

    Have you tried this ?

    // Test if both arrays are of the same type
    if (array1.class.getComponentType.equals(array2.class.getComponentTYpe)) {
        // Polymorphism FTW !
        return Arrays.equals(array1, array2);
    }
    
    0 讨论(0)
  • 2021-01-04 20:20

    Maybe the Strategy Pattern can help it look better :)

    0 讨论(0)
  • 2021-01-04 20:27

    I'm afraid the only alternative would be to use reflection, which would be nearly as ugly.

    Arrays.getClass()
          .getMethod("equals", new Class[]{obj1.getClass(), obj2.getClass()})
          .invoke(null, new object[]{obj1, obj2});
    

    Not tested, could fail in all kinds of ways, needs lots of exception handling...

    0 讨论(0)
  • 2021-01-04 20:32

    You can use reflection.

    public static boolean arrayEquals(Object arr1, Object arr2) throws Exception {
        Class<?> c = arr1.getClass();
        if (!c.getComponentType().isPrimitive()) {
            c = Object[].class;
        }
        Method m = Arrays.class.getMethod("equals", c, c);
        return (Boolean) m.invoke(null, arr1, arr2);
    }
    

    Reflection is only used to find the right method at run-time without the eyesore you're looking to avoid; the actual Arrays.equals method should run pretty fast.

    Obviously production version needs more robust exception handling. You may also want to use deepEquals(Object[], Object[]) instead of equals(Object[], Object[]) for non-primitive arrays.

    0 讨论(0)
  • 2021-01-04 20:34

    You can use the getClass() method without isArray(); check out this example:

    byte[] foo = { 1, 2 };
    byte[] bar = { 1, 2 };
    
    System.out.println(foo.getClass());
    System.out.println(bar.getClass());
    
    if(foo.getClass() == bar.getClass())
        System.out.println(Arrays.equals(foo, bar));
    

    I admit up front that this is far from a perfect solution. It shortens the potentially huge if-else chain that you had in the original post, but causes errors if the types are not the same. The following similar code wouldn't even compile in MyEclipse 8.0:

    byte[] obj1 = { 1, 2 };
    String[] obj2 = { "1", "2" };
    
    System.out.println(obj1.getClass());
    System.out.println(obj2.getClass());
    
    if(obj1.getClass().toString().equals(obj2.getClass().toString()))
        System.out.println(Arrays.equals(obj1, obj2));
    

    IF you are confident that you won't have type mismatches and your only problem is that you don't want to figure out which type you have, this could work.

    0 讨论(0)
提交回复
热议问题