공부/Java

[Java] Arrays 클래스 메서드 (자바의 정석)

leejinwoo1126 2023. 7. 31. 12:44
반응형

 

 


목차


    개인적으로 코딩 테스트, 알고리즘 문제 풀이시 아래의 static method 필수로 알고 있는 것이 좋다고 생각한다

    - Arrays.sort()

    - Arrays.fill()

    - Arrays.asList()

    - Arrays.stream()

    - Arrays.toString()

    - Arrays.copyOf()

    - Arrays.copyOfRange()


     

    배열의 동일성 확인

    (1) Arrays.equals(A, B)

    - 두 배열의 equlity(동일성) 확인

    - primitive type의 경우 값이 동일, reference type의 경우 참조 주소값이 동일한지 확인

    @DisplayName("")
    @Test
    void equalsTest() {
        // given
        int[] arr1 = {1, 2, 3};
        int[] arr2 = {1, 2, 3};
        int[] arr3 = {4, 5, 6};
    
        // when
        // then
        assertThat(Arrays.equals(arr1, arr2)).isTrue();
        assertThat(Arrays.equals(arr2, arr3)).isFalse();
    }

     

    (2) Arrays.deepEqual(A, B)

    - 2차원/다차원 배열의 equlity(동일성) 확인

    - primitive type의 경우 값이 동일, reference type의 경우 참조 주소값이 동일한지 확인

    @Test
    void deepEqualsTest() {
        // given
        int[][] arr1 = new int[][]{{1, 2}, {3, 4}};
        int[][] arr2 = new int[][]{{1, 2}, {3, 4}};
    
        String[][] arr3 = new String[][]{{"A", "B"}, {"C", "D"}};
        String[][] arr4 = new String[][]{{"E", "F"}, {"G", "H"}};
    
        // when
        // then
        assertThat(Arrays.deepEquals(arr1, arr2)).isTrue();
        assertThat(Arrays.deepEquals(arr3, arr4)).isFalse();
    }

     

    참고. 동등성(identity)과 동일성(equality)

    https://steady-coding.tistory.com/534

     

    [Java] 동일성(identity)과 동등성(equality)

    java-study에서 스터디를 진행하고 있습니다. 동일성 동일성은 동일하다는 뜻으로 두 개의 객체가 완전히 같은 경우를 의미한다. 여기서 완전히 같다는 뜻은 두 객체가 사실상 하나의 객체로 봐도

    steady-coding.tistory.com

     

     

    배열을 String 문자열로 변환

    (1) Arrays.toString(..)

    @DisplayName("Arrays.toString 은 1차원 배열을 인자로 받아 String 문자열 형태로 반환한다")
    @Test
    void toStringTest() {
        // given
        int[] arr1 = new int[]{1, 2, 3};
        String[] arr2 = new String[]{"A", "B", "C"};
    
        // when
    
        // then
        assertThat(Arrays.toString(arr1)).isEqualTo("[1, 2, 3]");
        assertThat(Arrays.toString(arr2)).isEqualTo("[A, B, C]");
    }

     

    (2) Arrays.deepToString(..)

    @DisplayName("Arrays.deepToString 은 2차원/다차원 배열 인자 받아 String 문자열로 변환하여 출력한다")
    @Test
    void deepToStringTest() {
        // given
        int[][] arr1 = new int[][]{{1, 2}, {3, 4}};
        String[][] arr2 = new String[][]{{"A", "B"}, {"C", "D"}};
        String[][][] arr3 = new String[][][]{{{"X"}, {"Y"}, {"Z"}}};
    
        // when
        // then
        assertThat(Arrays.deepToString(arr1)).isEqualTo("[[1, 2], [3, 4]]");
        assertThat(Arrays.deepToString(arr2)).isEqualTo("[[A, B], [C, D]]");
        assertThat(Arrays.deepToString(arr3)).isEqualTo("[[[X], [Y], [Z]]]");
    }

     

    배열 복사

    (1) Arrays.copyOf(배열, 복사할 요소 개수)

    @DisplayName("Arrays.copyOf 는 원본 소스 배열에서 지정한 길이만큼 요소를 복사한다")
    @Test
    void copyOfTest() {
        // given
        int[] nums = new int[]{1, 2, 3, 4, 5};
    
        // when
        int[] copyOfNum1 = Arrays.copyOf(nums, 3); // [1, 2, 3]
        int[] copyOfNum2 = Arrays.copyOf(nums, nums.length); // [1, 2, 3, 4, 5]
    
        // then
        assertThat(copyOfNum1).hasSize(3);
        assertThat(copyOfNum1).containsExactly(1, 2, 3);
    
        assertThat(copyOfNum2).hasSize(nums.length);
        assertThat(copyOfNum2).containsExactly(1, 2, 3, 4, 5);
        
        assertThat(Arrays.equals(nums, copyOfNum2)).isTrue(); // 배열 값 비교
    }

    - src : 소스 배열 

    - srcPos : 소스 배열의 시작 위치 (0번 인덱스 부터)

    - dest : 복사 배열

    - destPos : 복사할 시작 위치(0 번 인덱스부터)

    - length : 복사할 요소 개수

     

     

    (2) Arrays.copyOfRange(int[] original, int from, int to)

    시작과 종료(제외) 범위를 지정하여 소스 배열을 복사하여 리턴한다

     

    Parameter

    original_array 복사할 원본 배열
    from 시작 인덱스
    to 종료 인덱스 ( exclusive, 제외 )

     

    Exceptions

    ArrayIndexOutOfBoundsException 시작 인덱스가 소스 배열의 범위를 벗어 난 경우 
    IllegalArgumentException from > to 일때
    NullPointerException 소스 배열이 null 일때

     

    @DisplayName("")
    @Test
    void copyOfRangeTest() {
        // given
        int[] arr = {0, 1, 2, 3, 4, 5};
    
        // when
        int[] copy1 = Arrays.copyOfRange(arr, 1, 3); // [1, 2]
        int[] copy2 = Arrays.copyOfRange(arr, 0, arr.length); // [0, 1, 2, 3, 4, 5]
    
        // then
        assertThat(copy1).hasSize(2);
        assertThat(copy1).containsExactly(1, 2);
    
        assertThat(copy2).hasSize(6);
        assertThat(copy2).containsExactly(0, 1, 2, 3, 4, 5);
        
        assertThat(Arrays.equals(arr, copy2)).isTrue(); // 동일성 비교
    }

     

     

    (3) Arrays.copyOfRange(U[] original, int from, int to, Class newType) 

    소스 배열을 from ~ (to - 1) 범위까지 newType 형의 배열로 복사한다

    @DisplayName("")
    @Test
    void copyOfRangeWithClassTypeTest() {
        // given
        Student[] students = { new Student("홍길동", 15), new Student("이순신", 20) };
    
        // when
        Object[] copy = Arrays.copyOfRange(students, 0, 1, Object[].class);
    
        // then
        assertThat(copy).hasSize(1);
        assertThat(copy).extracting("name").containsExactly("홍길동");
    }

     

    배열 정렬

    Arrays.sort(..)

    - 기본적으로 오름차순 정렬 

    - 내림차순이나 다른 정렬기준을 사용하고 싶은 경우 primitive 타입을 wrapper class 타입으로 변환 후 Comparator 정의 

    @DisplayName("")
    @Test
    void sortTest() {
        // given
        int[] intArray = new int[]{5, 2, 1, 3, 4};
        Integer[] integers = Arrays.stream(intArray).boxed().toArray(Integer[]::new);
    
        // when
        Arrays.sort(intArray); // 기본 오름 차순 정렬, DualPivotQuicksort
        Arrays.sort(integers, Collections.reverseOrder()); // 내림 차순 정렬 위해서는 Wrapper 클래스 변환 후 Comparator 정의
    
        // then
        Assertions.assertThat(intArray).containsExactly(1, 2, 3, 4, 5);
        Assertions.assertThat(integers).containsExactly(5, 4, 3, 2, 1);
    }

     

     

    배열 요소 채우기

    (1) Arrays.fill(..)

    - 범위를 지정하지 않을 경우 배열 전체에 element 값을 val로 초기화

    - 범위 지정할 경우 from ~ (to - 1) 까지 element 값을 val로 초기화

    public static void fill(int[] source, int val) { .. }
    
    public static void fill(int[] source, int from, int to, int val) { .. }
    - from : start index
    - to : end index (exclusive, 제외)

     

    예시

    @DisplayName("Arrays.fill 을 사용하면 배열 요소를 원하는 값으로 초기화 할 수 있다")
    @Test
    void fillTest() {
        // given
        int[] dist = new int[5];
        boolean[] visit = new boolean[5];
    
        // when
        Arrays.fill(dist, Integer.MAX_VALUE);
        Arrays.fill(visit, 0, 4, true);
    
        // then
        assertThat(dist).containsOnly(Integer.MAX_VALUE);
        assertThat(visit).containsExactly(true, true, true, true, false);
    }

     

    (2) Arrays.setAll(..)

    배열의 인덱스 번호를 순차적으로 전달받아, 계산한 결과값을 해당 배열 인덱스에 반환하는 함수

     

    - int 값을 인자로 전달받아 연산 후 int 값을 리턴 해주는 @FunctionInterface

    @FunctionalInterface
    public interface IntUnaryOperator {
        int applyAsInt(int var1);
        
        //..
    }

     

    예시

    @DisplayName("Arrays.setAll 은 배열 인덱스를 인자로 전달 받아, 연산 처리 결과값을 해당 인덱스에 반환한다")
    @Test
    void setAllTest() {
        // given
        int[] data = new int[5];
    
        // when
        Arrays.setAll(data, (a) -> a * 10);
    
        // then
        assertThat(data).containsExactly(0, 10, 20, 30, 40);
    }

     

    배열 이진탐색

    Arrays.binarySearch(..)

    - 배열에 값이 존재하면 인덱스를 반환하고 없으면 -1 

    - 정렬(필수) 후 이진탐색 수행

     double[], float[] 실수 타입의 경우 없는 값을 이진탐색하게 되면, 예상치 못한 인덱스 값을 반환한다 
    - 실수의 부동 소수점으로 인한 현상
    - 실무에서 사용하거나, 코딩테스트에서 실수를 이진 탐색하는 경우는 없어 넘어감
    @DisplayName("binarySearch 는 탐색가 존재할 경우 인덱스를 반환하고, 없을 경우 -1을 반환한다")
    @Test
    void binarySearchTest() {
        // given
        char[] chars = {'x', 'a', 'z'};
        int[] ints = {6, 7, 4, 1, 5};
        float[] floats = {10.2f, 15.1f, 2.2f, 3.5f};
        double[] doubles = {10.0, 20.0, 15.0, 22.0 ,35.0};    	
        
        // 정렬 필수
        Arrays.sort(chars);
        Arrays.sort(ints);
        Arrays.sort(floats);
        Arrays.sort(doubles);
        
        // when
        // then
        assertThat(Arrays.binarySearch(chars, 'a')).isEqualTo(0);
        assertThat(Arrays.binarySearch(ints, 7)).isEqualTo(4);
        assertThat(Arrays.binarySearch(floats, 2.2f)).isEqualTo(0);
        assertThat(Arrays.binarySearch(doubles, 15.0)).isEqualTo(1);
    }

     

    Immutable List 생성

    Arrays.asList(..) 

    - 가변인자를 전달받아 ArrayList 생성하여 반환한다.

    - 이때 ArrayList는 java.util.Arrays.ArrayList 이다 (자주 사용하는 ArrayList는 java.util.ArrayList 이다)

     

    - new ArrayList() 생성자 호출시 E[] a 필드가 final이기 때문에 immutable 이다 (반대로 java.util.ArrayList는 mutable)

     

    예시

    immutable(불변) 인 List 객체를 수정하려하면 에러 발생 
    @DisplayName("Arrays.asList 가변 인자로 전달받은 값으로 ArrayList 를 생성하여 반환한다")
    @Test
    void asList() {
        // given
        List<Integer> list = Arrays.asList(4, 5, 7, 3); // java.util.Arrays.ArrayList, immutable
    
        // when
        // then
        assertThat(list).hasSize(4); // true
        assertThatThrownBy(() -> list.remove(0)).isInstanceOf(UnsupportedOperationException.class);
    }

     


    참고

    https://www.youtube.com/watch?v=N0zXNFPA8G8&list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp&index=50 

     

    https://www.youtube.com/watch?v=jKP2zX_p57c&list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp&index=126 

     

    https://umanking.github.io/2019/07/31/java-array-reverse-order/

     

    [Java] 배열 reverseOrder 하는 방법

    Java 배열 reverseOrder 하는 방법에 대해서 알아보자

    umanking.github.io

     

    반응형