[Java] 두 배열을 비교하는 방법

thsamajiki·2023년 7월 21일
0

두 배열을 비교하는 방법

Java에서 두 배열을 비교해야 하는 경우 다음 조건을 만족하면 동일하다고 판단한다.

  • 두 배열은 모두 동일한 타입입니다.

  • 두 배열은 동일한 수의 요소를 가지고 있으며, 정렬 순서도 동일해야 합니다.

  • 주소 값이 아닌 기본 타입의 값을 비교합니다.

  • 두 배열이 null로 할당되면 두 배열은 동일합니다.

Arrays 클래스에서 제공하는 equals() 메서드와 deepEquals() 메서드를 사용하여 두 배열을 비교해보겠다.

Arrays 클래스의 compare() 메서드를 사용하여 두 배열을 비교할 수 있지만, compare() 메서드는 Java 1.9 버전 이상부터 사용할 수 있으므로 이 글에서 언급하지는 않을 것이다.



== 연산자의 문제점

equals() 메소드와 deepEquals() 메소드 사용 방법을 설명하기 전에 2개의 배열을 == 연산자로 비교했을 때, 어떤 문제가 발생하는지 알아보자.

다음 예제는 1부터 3까지 정수 값을 가지는 int 타입의 두 배열을 == 연산자로 비교한다.

public static void main(String args[]) {
	int[] intArray1 = new int[] { 1, 2, 3 };
	int[] intArray2 = new int[] { 1, 2, 3 };

	if(intArray1 == intArray2) {
		System.out.println("두 배열은 동일합니다.");
	} else {
		System.out.println("두 배열은 동일하지 않습니다.");
	}
}

[실행 결과]

두 배열은 동일하지 않습니다.

int 타입의 배열 intArray1와 intArray2는 Heap 영역에 존재하는 배열의 값을 참조하고 있다.

따라서, 두 배열을 == 연산자로 비교하면 배열의 요소가 아닌 Heap 영역의 주소 값을 비교하므로 배열의 타입, 동일한 수의 요소 그리고 정렬 순서가 동일하더라도 두 배열은 동일하지 않다.



방법 1. Arrays 클래스의 equals 메서드

Arrays 클래스는 두 배열을 비교하는 equals() 메소드를 제공한다.

equals() 메서드는 주소 값이 아닌 배열의 요소를 비교한다.

두 배열이 동일한 타입, 동일한 수의 요소 그리고 정렬 순서가 동일한 경우 true를 반환하고 그렇지 않으면 false를 반환합니다.

다음 예제는 1부터 3까지 정수 값을 가지는 int 타입의 두 배열을 equals() 메서드로 비교합니다.

public static void main(String args[]) {
	int[] intArray1 = new int[] { 1, 2, 3 };
	int[] intArray2 = new int[] { 1, 2, 3 };

	if(Arrays.equals(intArray1, intArray2)) {
		System.out.println("두 배열은 동일합니다.");
	} else {
		System.out.println("두 배열은 동일하지 않습니다.");
	}
}

[실행 결과]

두 배열은 동일합니다.



방법 2. Arrays 클래스의 deepEquals 메서드

1차원 배열이 아닌 다차원 배열인 경우 equals() 메서드가 아닌 deepEquals() 메소드를 사용한다.

다음 예제는 int 타입의 2차원 배열을 equals() 메서드와 deepEquals() 메서드를 사용하여 비교한다.

public static void main(String args[]) {
	int[][] intArray1 = new int[][] 
	{
		{1, 2},
		{3, 4},
		{5, 6}
	};

	int[][] intArray2 = new int[][] 
	{
		{1, 2},
		{3, 4},
		{5, 6}
	};

	System.out.println("Arrays.equals() 메소드의 결과: " + 
		Arrays.equals(intArray1, intArray2));
          
	System.out.println("Arrays.deepEquals() 메소드의 결과: " + 
		Arrays.deepEquals(intArray1, intArray2));
}

[실행 결과]

Arrays.equals() 메소드의 결과: false
Arrays.deepEquals() 메소드의 결과: true



방법 3. 사용자 정의 클래스

배열의 타입이 사용자가 정의한 클래스 타입인 경우에는 두 배열을 비교하는 방법이 생각보다 복잡하다.

다음 소스 코드는 사용자가 직접 정의한 Person 클래스이다.

public class Person {
	private String Name;
	private Integer Age;

	public Person(String name, Integer age) {
		Name = name;
		Age = age;
	}

	public String getName() {
		return Name;
	}

	public void setName(String name) {
		Name = name;
	}

	public Integer getAge() {
		return Age;
	}

	public void setAge(Integer age) {
		this.Age = age;
	}
}

그리고 Person 타입의 두 배열을 비교하기 위해 equals() 메소드와 deepEquals() 메소드를 호출한다.
public static void main(String args[]) {
	Person[] personArray1 = new Person[] {
		new Person("둘리", 20),
		new Person("또치", 30)
	};

	Person[] personArray2 = new Person[] {
		new Person("둘리", 20),
		new Person("또치", 30)
	};

	System.out.println("Arrays.equals() 메소드의 결과: " +
		Arrays.equals(personArray1, personArray2));

	System.out.println("Arrays.deepEquals() 메소드의 결과: " +
		Arrays.deepEquals(personArray1, personArray2));
}

[실행 결과]

Arrays.equals() 메소드의 결과: false
Arrays.deepEquals() 메소드의 결과: false

제일 위에서 언급했듯이 주소값이 아닌 기본값을 비교해야 하는데, 배열의 요소가 객체이므로 주소값을 비교하게 된다.

사용자 정의 클래스 타입인 두 배열을 비교하려면, equals() 메서드와 hashCode() 메소드를 재정의한다.

다음 소스 코드는 Person 타입의 두 배열이 객체의 Name, Age 필드를 비교하도록 equals() 메서드와 hashCode() 메서드를 재정의한다.

public class Person {
	// 필드 및 프로퍼티는 위 소스 코드와 동일함...
	@Override
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null || getClass() != o.getClass())
			return false;
		Person person = (Person) o;

		return Objects.equals(Name, person.getName()) && Objects.equals(Age, person.getAge());
  }

	@Override
	public int hashCode() {
		return Objects.hash(Name, Age);
	}
}

이제, Person 타입의 두 배열이 동일한지 확인하기 위해 equals() 메서드와 deepEquals() 메소드를 호출합니다.

public static void main(String args[]) {
	Person[] personArray1 = new Person[] {
		new Person("둘리", 20),
		new Person("또치", 30)
	};

	Person[] personArray2 = new Person[] {
		new Person("둘리", 20),
		new Person("또치", 30)
	};

	System.out.println("Arrays.equals() 메소드의 결과: " +
		Arrays.equals(personArray1, personArray2));

	System.out.println("Arrays.deepEquals() 메소드의 결과: " +
		Arrays.deepEquals(personArray1, personArray2));
}

[실행 결과]

Arrays.equals() 메소드의 결과: true
Arrays.deepEquals() 메소드의 결과: true

마지막으로 객체의 필드 값이 다른 경우 false를 반환하는지 확인해보자.

두 배열은 두 번째 요소의 Age 필드의 값이 다르므로 false가 반환된다.

public static void main(String args[]) {
	Person[] personArray1 = new Person[] {
		new Person("둘리", 20),
		new Person("또치", 30)
	};

	Person[] personArray2 = new Person[] {
		new Person("둘리", 20),
		new Person("또치", 100)
	};

	System.out.println("Arrays.equals() 메소드의 결과: " +
		Arrays.equals(personArray1, personArray2));

	System.out.println("Arrays.deepEquals() 메소드의 결과: " +
		Arrays.deepEquals(personArray1, personArray2));
}

[실행 결과]

Arrays.equals() 메소드의 결과: false
Arrays.deepEquals() 메소드의 결과: false
profile
안드로이드 개발자

0개의 댓글