본문 바로가기

IT/Java

24_Java : API - Arrays 클래스 - 배열의 복사, 정렬, 검색

00. Aarrays 클래스

자바의 Arrays 클래스는 배열의 복사, 정렬, 검색 등 배열 조작 기능을 가지고 있다.

그 중 간단하지만 유용한 것 몇 가지를 정리해보았다.

 

01. 배열 복사

 

- System.arraycopy();

단순 복사의 경우 아래와 같이 System.arraycopy() 메소드를 사용할 수 있다.

중요한 점은 destination이 될 배열을 먼저 만들어 놓고(#6) 복사를 실행한다는 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ArrayCopyExample {
    public static void main(String[] args) {
        char[] arr1 = { 'J''A''V''A' };
 
        // 방법1
        char[] arr0 = new char[4];
        System.arraycopy(arr1, 0, arr0, 0, arr1.length);
        System.out.println(Arrays.toString(arr0));
        /*
         * System.arraycopy(src, srcPos, dest, destPos, length);
         * src − This is the source array.
         * srcPos − This is the starting position in the source array.
         * dest − This is the destination array.
         * destPos − This is the starting position in the destination data.
         * length − This is the number of array elements to be copied.
         * 
         */
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

실행결과 : [J, A, V, A]

 

그렇다면 아래처럼 복사 범위를 살짝 바꾸면 어떻게 될까?

arr1의 데이터를 1번 인덱스 부터 총 두 개 복사하였으니 [A, V]가 출력될까?

1
2
3
4
5
6
7
8
9
10
public class ArrayCopyExample {
    public static void main(String[] args) {
        char[] arr1 = { 'J''A''V''A' };
 
        // 방법1
        char[] arr0 = new char[4];
        System.arraycopy(arr1, 1, arr0, 0, 2);
        System.out.println(Arrays.toString(arr0));
 
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

실행결과 : [A, V,    ,    ,]

 

막상 실행해보면 생각한 것과 다른 결과가 나올 수도 있다.

왜 그럴까?

처음에 char[] arr0 = new char[4]; 라는 코드를 통해 4칸짜리 빈 배열을 만들어놨다.

즉, 빈 방이 네 개 있었는데 그 중 0번 방 부터 'A', 'V' 라는 두 개의 값을 복사하여 채워넣은 것이다.

그렇다고 빈 방이 없어지지는 않기 때문에 2번 인덱스와 3번 인덱스 역시 존재하는 것이다. (null값)

 

- Arrays.copyOf();

한편, Arrays.copyOf(원본배열, 복사할 길이); 메소드를 사용하여 배열을 복사할 수도 있다.

이 때는 빈 배열을 미리 만들지 않아도 된다.

아래의 경우, arr1을 그 길이만큼 복사하여 새로운 배열 arr2를 만들었다.

1
2
3
4
5
6
7
8
9
10
11
public class ArrayCopyExample {
    public static void main(String[] args) {
        char[] arr1 = { 'J''A''V''A' };
 
        char[] arr2 = Arrays.copyOf(arr1, arr1.length);
        System.out.println(Arrays.toString(arr2));
        /*
         *  char[] arr2 = Arrays.copyOf(original, newLength)
         */
 
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

출력결과 : [J, A, V, A]

 

- Arrays.copyOfRange();

Arrays.copyOfRange(원본배열, 시작인덱스, 끝 인덱스); 메소드를 사용하여 원하는 범위만 복사할 수도 있다.

단, 시작인덱스는 포함되고 끝 인덱스는 포함되지 않는다!!!

이 때도 역시 빈 배열을 미리 만들지 않아도 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
public class ArrayCopyExample {
    public static void main(String[] args) {
        char[] arr1 = { 'J''A''V''A' };
 
        
        char[] arr3 = Arrays.copyOfRange(arr1, 13); // arr1[1]~arr1[2]를 arr3에 복사
        System.out.println(Arrays.toString(arr3));
        /* char[] arr3 = Arrays.copyOfRange(original, from, to)
         * original : 원본 배열
         * from : 시작인덱스
         * to : 끝 인덱스 */
 
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

출력결과 : [A, V]

 

02. 배열 항목 정렬

 

- Arrays.sort() 메소드

Arrays.sort() 메소드를 사용하면 배열의 각 항목을 오름차순으로 정렬할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
public class SortExample2 {
    public static void main(String[] args) {
 
        // 기본 타입
        int[] scores = { 5060309020 };
        Arrays.sort(scores);
        for (int score : scores) {
            System.out.print(score + " ");
        }
        System.out.println();
 
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

실행결과 : 20 30 50 60 90 => 배열이 오름차순 정렬 된 상태로 '저장'까지 됨을 알 수 있다.

 

물론, 참조형타입도 정렬 가능하다.

내림차순으로 정렬해주는 메소드는 없지만 for문을 활용하여 역순으로 출력하는 것은 가능하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class SortExample2 {
    public static void main(String[] args) {
 
        // 참조타입
        String names[] = { "Mateo""Alice""Yazmin""Thomas" };
        Arrays.sort(names);
        for (String name : names) {
            System.out.print(name + " ");
        }
        System.out.println();
        // 거꾸로 출력하기
        for (int i = names.length-1; i >= 0; i--) {
            System.out.print(names[i] + " ");
        }
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

실행결과 :

Alice Mateo Thomas Yazmin 
Yazmin Thomas Mateo Alice 

 

- 사용자 정의 클래스의 정렬

그렇다면 사용자 정의 클래스도 정렬할 수 있을까? 당연하다.

단, 해당 클래스가 Comparable 인터페이스를 구현하고 있어야 한다.

 

Person 클래스이다.

이 때 age를 기본타입인 int로 선언할 경우 compareTo 메소드에서 예외가 발생하므로 Integer로 선언한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Person implements Comparable<Person>{    //SortExample3 클래스와 짝임
    
    String name;
    Integer age;
    
    Person(String name){
        this.name = name;
    }
    
    Person(Integer age) {
        this.age = age;
    }
    
    Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    
    
 
    @Override
    public int compareTo(Person o) {
        // TODO Auto-generated method stub
        return name.compareTo(o.name);
//        return age.compareTo(o.age);    //메인에서 Arrays.sort를 실행하면, 리턴타입 기준으로 정렬 된다
    }
 
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

메인클래스

일부러 다양한 생성자를 활용하여 객체를 만들었다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class SortExample3 {    //Person 클래스와 짝이다
    public static void main(String[] args) {
        //다양한 생성자 활용
        Person p1 = new Person("홍길동");
        p1.age = 18;
        Person p2 = new Person(20);
        p2.name = "강감찬";
        Person p3 = new Person("임꺽정"30);
        
        //Person 클래스 주석 번갈아가며 실행해본다.
        Person[] ppl = {p1, p2, p3};
        Arrays.sort(ppl);
        for(int i=0; i < ppl.length; i++) {
            System.out.print(ppl[i].name + " ");
        }
        System.out.println();
        
        Arrays.sort(ppl);
        for(int i=0; i < ppl.length; i++) {
            System.out.print(ppl[i].age + " ");
        }
    }//end main
 
}//end clas
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

Person 클래스의 compareTo 메소드로 인해 현재 이름순으로 오름차순 정렬되었으므로 실행결과는 다음과 같다.

실행결과 :

강감찬 임꺽정 홍길동 
20 30 18 

 

만일 주석 처리 된 부분을 바꿔 실행한다면 나이 순으로 오름차순 정렬되며, 실행결과는 다음과 같다.

실행결과 :

홍길동 강감찬 임꺽정 
18 20 30 

03.배열 검색

- Arrays.binarySearch() 메소드를 활용하여 배열 내에서 찾으려는 항목의 인덱스를 검색할 수 있다.

Arrays.binarySearch(배열명, 데이터); 형태로 사용하며, 해당 항목의 인덱스를 int형으로 리턴한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class SearchExample {    //검색하려면 먼저 sort로 오름차순 정렬을 해 줘야 한다.
    public static void main(String[] args) {
        // 기본 타입만 검색
        int[] scores = { 999798 };
        Arrays.sort(scores);    //sort를 하지 않고 실행해보자
        int index = Arrays.binarySearch(scores, 99);
        System.out.println("찾은 인덱스 : " + index);
 
        // 문자열 검색
        String[] names = { "자바""파이선""씨언어" };
        Arrays.sort(names);
        index = Arrays.binarySearch(names, "씨언어");
        System.out.println("찾은 인덱스 : " + index);
        
        System.out.println("toString 해보자 : " + Arrays.toString(names));
 
        // 객체 검색
        Member m1 = new Member("홍길동"18);
        Member m2 = new Member("박문수"32);
        Member m3 = new Member("김유신"26);
        Member[] members = { m1, m2, m3 };
        Arrays.sort(members);
        index = Arrays.binarySearch(members, m1);
        System.out.println("찾은 인덱스 : " + index);
        
    }
 
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter