Post

[Java] Arrays

[Java] Arrays

Arrays란


Arrays는 배열과 관련된 다양한 유틸리티 메소드를 제공하는 유틸리티 클래스입니다. 이 클래스는 ‘java.util’ 패키지에 속해 있으며, 배열의 조작을 더 쉽게 해주는 여러 가지 정적(static) 메서드를 포함하고 있습니다. 같은 기능의 메서드가 배열의 타입만 다르게 오버로딩되어 있어 많게 느껴지지만 실제로는 그렇게 많지 않습니다.


배열의 복사

  • copyOf()
    copyOf()는 배열전체를 복사해서 새로운 배열을 만들어 반환합니다.

    1
    2
    3
    4
    
    int[] arr = {0, 1, 2, 3, 4};
    int[] arr2 = Arrays.copyOf(arr, arr.length);  // arr2 = [0, 1, 2, 3, 4]
    int[] arr3 = Arrays.copyOf(arr, 3);           // arr3 = [0, 1, 2]
    int[] arr4 = Arrays.copyOf(arr, 7);           // arr4 = [0, 1, 2, 3, 4, 0, 0]
    
  • copyOfRange()
    copyOfRange()는 배열의 일부를 복사해서 새로운 배열을 만들어 반환합니다.

    1
    2
    3
    
    int[] arr = {0, 1, 2, 3, 4};
    int[] arr5 = Arrays.copyOfRange(arr, 2, 4);           // arr5 = [2, 3]
    int[] arr6 = Arrays.copyOfRange(arr, 0, 7);           // arr6 = [0, 1, 2, 3, 4, 0, 0]
    


배열 채우기


  • fill()
    fill()은 배열의 모든 요소를 지정된 값으로 채웁니다.

    1
    2
    
    int[] arr = new int[5];
    Arrays.fill(arr, 9);    // arr = [9, 9, 9, 9, 9]
    
  • setAll()
    setAll()은 배열을 채우는데 사용할 함수형 인터페이스를 매개변수로 받습니다. 이 메서드를 호출할 때는 함수형 인터페이스를 구현한 객체를 매개변수로 지정하거나 람다식을 지정해야합니다.

    1
    2
    
    int[] arr =  new int[5];
    Arrays.setAll(arr, () -> (int)(Math.random() * 5) + 1);  // arr = [1, 5, 2, 1, 1]
    

    위의 setAll()예시에 사용된 ‘i -> (int)(Math.random() * 5) + 1 은 람다식인데, 1 ~ 5의 범위에 속한 임의의 정수를 반환하는 일을 합니다. 그리고 setAll()메서드는 이 람다식이 반환한 임의의 정수로 배열을 채웁니다.


배열의 정렬과 검색


  • sort()
    sort()는 배열을 정렬할 때 사용합니다

    1
    2
    3
    
    int[] arr = {3, 2, 0, 1, 4};
    Arrays.sort(arr);                           // 배열 arr을 정렬합니다.
    System.out.println(Arrays.toString(arr));   // [0, 1, 2, 3, 4]
    
  • binarySearch()
    binarySearch()는 배열에 저장된 요소를 검색할 때 사용합니다.

    1
    2
    3
    4
    5
    
    int[] arr = {3, 2, 0, 1, 4};
    int idx = Arrays.binarySearch(arr, 2);  // idx = -5  <- 잘못된 결과
    
    Arrays.sort(arr);
    int idx = Arrays.binarySearch(arr, 2);  // idx = 2  <- 올바른 결과
    

    배열의 첫 번째 요소부터 순서대로 하나씩 검색하는 것을 순차검색이라고 하는데, 이 검색 방법은 배열이 정렬되어 있을 필요는 없지만 배열의 요소를 하나씩 비교하기 때문에 시간이 많이 걸립니다. 반면에 이진검색은 배열의 검색할 범위를 반복적으로 절반씩 줄여가면서 검색하기 때문에 검색속도가 상당히 빠릅니다. 배열의 길이가 10배가 늘어나도 검색 횟수는 3 ~ 4회 밖에 늘어나지 않으므로 큰 배열의 검색에 유리합니다. 단, 배열이 정렬되어 있는 경우에만 사용할 수 있다는 단점이 있습니다.


문자열의 비교와 출력 - equals(), toString()


toString()배열의 모든 요소를 문자열로 편하게 출력할 수 있습니다. toString()은 일차원 배열에만 사용할 수 있으므로, 다차원 배열에는 deepTo String()을 사용해야 합니다. deepToString()은 배열의 모든 요소를 재귀적으로 접근해서 문자열을 구성하므로 2차원뿐만 아니라 3차원 이상의 배열에도 동작합니다.

1
2
3
4
5
int[] arr = {0, 1, 2, 3, 4};
int[][] arr2D = { {11, 12}, {21, 22} };

System.out.println(Arrays.toString(arr)) // [0, 1, 2, 3, 4]
System.out.println(Arrays.deepToString(arr2D)) // [[11, 12], [21, 22]]

equals()는 두 배열에 저장된 모든 요소를 비교해서 같으면 true, 다르면 false를 반환합니다. equals()도 일차원 배열에만 사용가능하므로, 다차원 배열의 비교에는 deepEquals()를 사용해야합니다.

1
2
String[][] str2D  = new String[][] { {"aaa", "bbb"}, {"AAA", "BBB"} };
String[][] str2D2 = new String[][] { {"aaa", "bbb"}, {"AAA", "BBB"} };

위와 같이 2차원 String배열을 equals()로 비교하면 배열에 저장된 내용이 같은데도 false를 결과로 얻습니다. 다차원 배열은 ‘배열의 배열’의 형태로 구성하기 때문에 equals()로 비교하면, 문자열을 비교하는 것이 아니라 ‘배열에 저장된 배열의 주소’를 비교하게 됩니다. 서로 다른 배열은 항상 주소가 다르므로 false를 결과로 얻습니다.


배열을 List로 변환 - asList(Object… a)


asList()는 배열을 List에 담아서 반환합니다. 매개변수의 타입이 가변인수라서 배열 생성없이 저장할 요소들만 나열하는 것도 가능합니다.

1
2
3
List list = Arrays.asList(new Integer[]{1, 2, 3, 4, 5});  // list = [1, 2, 3, 4, 5]
List list = Arrays.asList(1, 2, 3, 4, 5);                 // list = [1, 2, 3, 4, 5]
list.add(6);  // UnsupportedOperationException 예외 발생

한 가지 주의할 점은 asList()가 반환한 List의 크기를 변경할 수 없다는 것입니다. 즉, 추가 또는 삭제가 불가능합니다. 저장된 내용은 변경가능하나, 만일 크기를 변경할 수 있는 List가 필요하다면 다음과 같이 하면 됩니다.

1
List list = new ArrayList(Arrays.asList(1, 2, 3, 4, 5));

읽어주셔서 감사합니다. 😊

Reference
자바의 정석 - 남궁성

This post is licensed under CC BY 4.0 by the author.