java.util.Arrays.equals() with limited length

2020-02-13 01:37发布

问题:

I need to compare elements of two byte[] arrays but only up to fixed length. For whole arrays I use java.util.Arrays.equals(). Of course I can copy sub-ranges (Arrays.copyOf()) but I'd like not to do so. I am also sure there should be standard way to do so without new utility method implementation.

What I need formally is something like:

java.util.Arrays.equals(byte[] a, byte [] b, int length)

Any point to something well known? I don't see widely used approach.

Again about what is asked to prevent false answers: - Array equals with limit on length. - I HAVE manual implementation but I'd like to replace it with something standard. - I don't want any copy.

Thank you in advance.

回答1:

ByteBuffer provides something similar to what @meriton proposed but can work with primitives. Here is illustrative code:

import java.nio.ByteBuffer;

public class Main {

    public static void main(String [] args) throws Exception {

        byte [] a1 = {0, 1, 0, 1};
        byte [] a2 = {0, 0, 1, 0};

        boolean eq = ByteBuffer.wrap(a1,0,3).equals(ByteBuffer.wrap(a2,1,3));
        System.out.println("equal: " + eq);
    }
}

Properties of @meriton answer:

  • Result is collection with full power of using them.
  • Actually it is somewhat copy (but not full).
  • Requires references, primitives cannot be wrapped in this way.

This answer specials.

  • Backend array is NOT CHANGED in any way. ByteBuffer.array() returns reference to original array (could be disadvantage, could be advantage).
  • It works with primitives.


回答2:

You could do:

Arrays.asList(a).subList(0,n).equals(Arrays.asList(b).subList(0,n))


回答3:

You could based your method throught the source code of Arrays.equals.

public static boolean equals(byte[] a, byte[] a2, int length) {
        if (a==a2)
            return true;
        if (a==null || a2==null)
            return false;

        for (int i=0; i<length; i++)
            if (a[i] != a2[i])
                return false;

        return true;
    }


回答4:

This feature is added in Java 9. Given array a and array b, you would do:

//with char array
    Arrays.compare(a, startIndex_A, endIndex_A, b, startIndex_B, endIndex_B);

//with byte, short, int, long arrays
    Arrays.compareUnsigned(a, startIndex_A, endIndex_A, b, startIndex_B, endIndex_B);


回答5:

Why not trivially implement it yourself?

public static void firstNEqual(byte[] a, byte[] b, int n) {
    assert a.length >= n && b.length >= n;

    for(int i = 0; i < n; i++)
        if(a[i] != b[i])
            return false;
    return true;
}

What makes you think there should be a utility method built in? What if my condition is a[1:4] == b[0:3]? Is that more readable as Arrays.subrangesEqual(a, b, 1, 0, 3), or as an explicit for loop:

for(int i = 1, j = 0, count = 0; count < 3; count++, i++, j++)
    if(a[i] != b[j])
        return false;
return true;