So sánh hai Mảng Byte? (Java)


96

Tôi có một mảng byte với ~ dãy nhị phân đã biết trong đó. Tôi cần xác nhận rằng chuỗi nhị phân là những gì nó phải như vậy. Tôi đã thử .equalsthêm vào ==, nhưng không hiệu quả.

byte[] array = new BigInteger("1111000011110001", 2).toByteArray();
if (new BigInteger("1111000011110001", 2).toByteArray() == array){
    System.out.println("the same");
} else {
    System.out.println("different'");
}

bạn có thể chỉ so sánh các chuỗi trực tiếp không?
vật thể

1
@objects - số 0 ở đầu. Bên cạnh đó, thứ String / BigInteger có thể chỉ là một cách minh họa cho câu hỏi so sánh mảng byte.
Stephen C

Bạn đã thử sử dụng phương thức CompareTo chưa? BTW ==so sánh các giá trị nguyên thủy chỉ là fyi
ChriskOlson

Đây là câu hỏi có liên quan về mảng phần so sánh: stackoverflow.com/questions/16646967/...
Vadzim

Câu trả lời:


165

Trong ví dụ của bạn, bạn có:

if (new BigInteger("1111000011110001", 2).toByteArray() == array)

Khi xử lý các đối tượng, ==trong java so sánh các giá trị tham chiếu . Bạn đang kiểm tra xem tham chiếu đến mảng được trả về toByteArray()có giống với tham chiếu được giữ trong arrayđó hay không, điều này tất nhiên không bao giờ có thể đúng. Ngoài ra, các lớp mảng không ghi đè .equals()nên hành vi của lớp Object.equals()đó cũng chỉ so sánh các giá trị tham chiếu.

Để so sánh nội dung của hai mảng, các phương thức so sánh mảng tĩnh được cung cấp bởi lớp Arrays

byte[] array = new BigInteger("1111000011110001", 2).toByteArray();
byte[] secondArray = new BigInteger("1111000011110001", 2).toByteArray();
if (Arrays.equals(array, secondArray))
{
    System.out.println("Yup, they're the same!");
}


11

Java không quá tải các toán tử, vì vậy bạn thường sẽ cần một phương thức cho các kiểu không cơ bản. Hãy thử phương thức Arrays.equals () .


11

Bạn có thể sử dụng cả hai Arrays.equals()MessageDigest.isEqual(). Hai phương pháp này có một số khác biệt.

MessageDigest.isEqual()là một phương pháp so sánh Arrays.equals()không đổi theo thời gian và không cố định theo thời gian và nó có thể gây ra một số vấn đề bảo mật nếu bạn sử dụng nó trong ứng dụng bảo mật.

Chi tiết về sự khác biệt có thể được đọc tại Arrays.equals () so với MessageDigest.isEqual ()


3

Tất nhiên, câu trả lời được chấp nhận của Arrays.equal (byte [] đầu tiên, byte [] thứ hai) là đúng. Tôi thích làm việc ở cấp độ thấp hơn, nhưng tôi không thể tìm thấy chức năng hiệu quả ở cấp độ thấp để thực hiện các phạm vi kiểm tra bình đẳng. Tôi đã phải tự quất, nếu ai đó cần:

public static boolean ArraysAreEquals(
 byte[] first,
 int firstOffset,
 int firstLength,
 byte[] second,
 int secondOffset,
 int secondLength
) {
    if( firstLength != secondLength ) {
        return false;
    }

    for( int index = 0; index < firstLength; ++index ) {
        if( first[firstOffset+index] != second[secondOffset+index]) {
            return false;
        }
    }

    return true;
}

Đây là một giải pháp tốt để kiểm tra một tập hợp con của các mảng thay vì toàn bộ. Tuy nhiên, lưu ý rằng Arrays.equals (byte [], byte []) thực hiện khá chính xác mọi thứ bạn đã làm ở đây (ngoại trừ việc xử lý hai giá trị là cùng một đối tượng hiệu quả hơn và xử lý các mảng rỗng được chuyển một cách duyên dáng). Khi được lựa chọn sử dụng triển khai thư viện tiêu chuẩn sẽ được cộng đồng hỗ trợ hoặc viết một triển khai tùy chỉnh về nó mà tôi sẽ cần hỗ trợ mãi mãi, tôi sẽ chọn cách cũ mọi lúc.
Tom Dibble

4
Câu trả lời hữu ích cho trường hợp sử dụng trong đó một người có hai mảng và muốn so sánh phạm vi byte từ chúng, mà không cần tạo bản sao của mảng trước. Bản sao mảng thêm chi phí, thêm rác và không cần thiết. Những gì tôi cần là một memcmp kiểu c cấp thấp () và điều này phù hợp với nhu cầu. Tất nhiên, memcmp () chỉ có 1 đối số độ dài. Chức năng này đủ gần.
Bamaco

2

Vì tôi muốn so sánh hai mảng cho một bài kiểm tra đơn vị và tôi đã tìm được câu trả lời này, tôi nghĩ tôi có thể chia sẻ.

Bạn cũng có thể làm điều đó với:

@Test
public void testTwoArrays() {
  byte[] array = new BigInteger("1111000011110001", 2).toByteArray();
  byte[] secondArray = new BigInteger("1111000011110001", 2).toByteArray();

  Assert.assertArrayEquals(array, secondArray);
}

Và bạn có thể kiểm tra So sánh các mảng trong các xác nhận JUnit để biết thêm thông tin.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.