
Arrays 클래스는 배열(Array)을 다루기 위한 유틸리티 메서드들을 모아둔 클래스다.
java.util 패키지에 포함되어 있으며 다음과 같이 사용할 수 있다.
import java.util.Arrays;
Arrays 클래스의 모든 메서드는 static으로 제공되기 때문에
객체를 생성하지 않고 클래스 이름을 통해 바로 사용할 수 있다.
int[] numbers = {3, 1, 2};
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers)); // [1, 2, 3]
배열은 System.out.println()으로 바로 출력할 경우
배열의 주소값이 출력된다.
int[] iArray = {2, 7, 5, 1, 3};
String[] sArray = {"멜론", "orange", "Apple", "banana", "apple", "레몬", "apeach"};
// 배열의 주소값 출력
System.out.println(iArray); // [I@7cca494b
System.out.println(sArray); // [Ljava.lang.String;@7ba4f24f
이때, Arrays.toString()을 사용하여 배열의 요소를 확인할 수 있다.
// 배열의 요소 출력
System.out.println(Arrays.toString(iArray));
// [2, 7, 5, 1, 3]
System.out.println(Arrays.toString(sArray));
// [멜론, orange, Apple, banana, apple, 레몬, apeach]
Arrays.sort()는 배열을 기본 오름차순으로 정렬한다.
int[] iArray = {2, 7, 5, 1, 3};
String[] sArray = {"멜론", "orange", "Apple", "banana", "apple", "레몬", "apeach"};
// 배열 정렬 (오름차순)
Arrays.sort(iArray);
Arrays.sort(sArray);
System.out.println(Arrays.toString(iArray));
// [1, 2, 3, 5, 7]
System.out.println(Arrays.toString(sArray));
// [Apple, apeach, banana, orange, 멜론, 레몬]
이때, 정렬 기준은 다음과 같다.
숫자 배열 → 값 기준 오름차순
문자열 배열 → 유니코드(사전순) 기준
즉, 대문자가 소문자보다 먼저 정렬되는 이유도
문자열이 문자 코드 기준으로 비교되기 때문이다.
Arrays.sort()는 기본적으로 오름차순만 제공한다.
따라서 내림차순 정렬이 필요한 경우
오름차순으로 정렬한 뒤 값을 반대로 새로운 배열에 대입하는 방식으로
직접 구현할 수 있다.
String[] sArray = {"멜론", "orange", "Apple", "banana", "apple", "레몬", "apeach"};
// 1. 오름차순 정렬
Arrays.sort(sArray);
System.out.println(Arrays.toString(sArray));
// [Apple, apeach, apple, banana, orange, 레몬, 멜론]
// 2. 역순으로 새 배열에 대입
String[] reverse = new String[sArray.length];
for (int i = 0; i < sArray.length; i++) {
reverse[i] = sArray[sArray.length - 1 - i];
}
System.out.println(Arrays.toString(reverse));
// reverse → [멜론, 레몬, orange, banana, apple, apeach, Apple]
하지만, 이 방식은 코드가 길어지고
인덱스 계산 과정에서 실수가 발생할 수 있기 때문에
다음과 같은 방법을 사용할 수 있다.
객체 타입 배열(String[], Integer[])의 경우에는
Collections.reverseOrder()를 사용하면 내림차순 정렬을 처리할 수 있다.
String[] sArray = {"멜론", "orange", "Apple", "banana", "apple", "레몬", "apeach"};
// Array.sort() 메서드에 Collections.reverseOrder()를 전달한다.
Arrays.sort(sArray, Collections.reverseOrder());
System.out.println(Arrays.toString(sArray));
// [멜론, 레몬, orange, banana, apple, apeach, Apple]
// int[] 기본 타입 배열 사용 불가
// Wraaper 클래스 사용
Integer[] iArray = {2, 7, 5, 1, 3};
Arrays.sort(iArray, Collections.reverseOrder());
System.out.println(Arrays.toString(iArray));
// [7, 5, 3, 2, 1]
다만, 이 방식은 기본 타입 배열(int[])에는 사용할 수 없다.
(Integer[]로 변환해야 함)
이는 Collections.reverseOrder()는
Comparator<T> 기반이라 객체 타입 배열에서만 사용할 수 있기 때문이다.
배열은 == 연산자로 비교하면 주소값만 비교한다.
int[] a = {1, 2, 3};
int[] b = {1, 2, 3};
System.out.println(a == b); // false
이때, 배열의 요소가 같은지 비교하려면
Arrays.equals()를 사용해야 한다.
int[] a = {1, 2, 3};
int[] b = {1, 2, 3};
System.out.println(Arrays.equals(a, b)); // true
Arrays.equals()는 두 배열이 같은 배열인지를 단순히 참조로 비교하지 않고
배열에 담긴 내용을 기준으로 비교한다.
먼저 두 배열의 길이를 비교한다.
배열의 길이가 다르면, 요소를 비교할 필요도 없이 결과는 false가 된다.
길이가 같은 경우에만 다음 단계로 넘어간다.
그 다음에는 배열의 처음 인덱스부터 끝까지 순서대로 요소를 하나씩 비교한다.
같은 인덱스에 위치한 값이 하나라도 다르면 즉시 false를 반환하고
모든 요소가 동일한 경우에만 true를 반환한다.
이 때문에 Arrays.equals()는
배열의 길이, 요소의 값, 그리고 요소의 순서가 모두 같을 때만 true가 된다.
Arrays.copyOf()는
배열을 복사하면서 길이까지 지정할 수 있는 메서드다.
(단, 반드시 길이를 지정해야 한다.)
int[] origin = {1, 2, 3};
int[] copy1 = Arrays.copyOf(origin, 2);
int[] copy2 = Arrays.copyOf(origin, 3);
int[] copy3 = Arrays.copyOf(origin, 5);
System.out.println(copy1);
// [1, 2]
System.out.println(copy2);
// [1, 2, 3]
System.out.println(copy3); // 길이가 늘어나면 기본값으로 채움
// [1, 2, 3, 0, 0]
이때, Object에서 상속받아 배열에서 재정의되는
clone() 메서드도 같은 의미로 사용된다.
// 모든 배열이 기본적으로 가지고 있는 메서드
// 단, 길이 조절 불가 (원본과 동일한 길이)
int[] origin = {1, 2, 3};
int[] copy = origin.clone();
System.out.println(copy);
// [1, 2, 3]
위 두 메서드는 공통적으로
원본 배열은 건드리지 않고
새로운 배열을 반환한다. (원본 보호용 복사)
또한, 모두 얕은 복사이므로, 객체 배열에서는 요소 참조를 공유한다.
(얕은 복사 vs 깊은 복사) 개념은 추후에 서술하겠다.
[프로그래머스 코딩테스트 입문] A로 B 만들기 - Arrays.equals( )
[프로그래머스 코딩테스트 입문] 외계어 사전 - Arrays.equals( )
[프로그래머스 코딩테스트 입문] 등수 매기기 - 정렬된 배열과 원본 비교를 통한 순위 계산