[java] 배열 동작 방식 파악

송어·2023년 11월 15일

IntArray

배열의 동작 방식을 파악해보기 위해 배열을 직접 사용하지 않고 배열처럼 작동하는 API를 만들어보았다.

  1. 초기 공간을 5로 설정
  2. 설정한 초기 공간을 int[] element에 할당하며 생성하는 intArray()메서드 설계
  3. 현재 배열의 용량을 알 수 있는 size()메서드 설계
  4. 생성한 배열에 요소를 저장할 수 있는 add()메서드 설계
    (배열 용량이 다 찬경우 현재 크기에서 2배만큼 늘림)
  5. 해당되는 배열 인덱스의 값을 개별 반환하는 get()메서드 설계
    (인덱스 범위에 벗어나는 매개변수를 받을 경우 indexOutBoundsException 날림)
import java.util.Arrays;

public class IntArray {
    private int[] elements; // 배열 선언
    private int size = 0; // 초기 용량 설정

    public IntArray() { // 객체 생성시 배열 생성 및 크기 할당되도록 설계
        // 초기 크기 설정
        final int DEFAULT_CAPACITY = 5;
        elements = new int[DEFAULT_CAPACITY];
    }
    public int length() { // 현재 배열의 길이를 반환하는 메서드
        return elements.length;
    }

    public int size() { // 현재 배열의 용량을 반환하는 메서드
        return size;
    }

    public int get(int index) { // 인덱스에 해당하는 배열에 저장된 개별값을 반환하는 메서드
        if(index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("범위를 초과했습니다.");
        }
        return elements[index];
    }

    public void add(int element) { // 배열에 값을 저장하는 메서드
        if(size == elements.length) {
            ensureCapacity();
        }
        elements[size++] = element;
    }

    private void ensureCapacity() { // 배열의 길이를 늘려 반환하는 메서드
        int newCapacity = elements.length * 2;
        elements = Arrays.copyOf(elements, newCapacity);
    }
    /*
     * Arrays.copyOf(T[] original, int newLength)
     * - 파라미터로 받은 배열을 복사해 새로운 배열을 만들어서 반환
     * - 리턴되는 새로운 배열의 길이는 2번째 파라미터로 지정
     */
}

Arrays.copyOf()메서드는 배열을 복사하는 기능을 가진다.
파라미터로 배열과 배열의 길이를 받아서 새로 설정한 길이로 배열을 복사한다.

BookArray

같은 방법으로 객체를 담는 배열을 만들었다.

import java.util.Arrays;

public class BookArray {
    private Book[] elements; // 배열 선언
    private int size = 0; // 초기 용량 설정

    public BookArray() { // 객체 생성시 배열 생성 및 크기 할당되도록 설계
        // 초기 크기 설정
        final int DEFAULT_CAPACITY = 5;
        elements = new Book[DEFAULT_CAPACITY];
    }
    public int length() { // 현재 배열의 길이를 반환하는 메서드
        return elements.length;
    }

    public int size() { // 현재 배열의 용량을 반환하는 메서드
        return size;
    }

    public Book get(int index) { // 인덱스에 해당하는 배열에 저장된 개별값을 반환하는 메서드
        if(index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("범위를 초과했습니다.");
        }
        return elements[index];
    }
    
    public String getAll() { // 모든 배열을 출력(줄바꿈 추가)
            return Arrays.toString(elements).replace("}, ", "}\n");
        }

    public void add(Book element) { // 배열에 값을 저장하는 메서드
        if(size == elements.length) {
            ensureCapacity();
        }
        elements[size++] = element;
    }

    private void ensureCapacity() { // 배열의 길이를 늘려 반환하는 메서드
        int newCapacity = elements.length * 2;
        elements = Arrays.copyOf(elements, newCapacity);
    }
}
public class Book {
    private String title;
    private int price;
    private String publisher;
    private String author;

    public Book(String title, int price, String publisher, String author) {
        this.title = title;
        this.price = price;
        this.publisher = publisher;
        this.author = author;
    }

    @Override
    public String toString() {
        return "Book{" +
                "title='" + title + '\'' +
                ", price=" + price +
                ", publisher='" + publisher + '\'' +
                ", author='" + author + '\'' +
                '}';
    }
}

Book Model을 설계하는 과정에서 값 저장을 생성자를 통해서만 할 수 있도록 생성자 주입 방식의 객체 생성 방식을 선택하고 개별 값은 저장할 수 없도록 배열 특성 상 객체의 속성값을 개별적으로 저장할 수 없도록 setter()메서드는 설계하지 않았다.

다만, BookArray의 get()메서드로 배열의 개별 객체를 반환하면서 객체의 개별 속성에 접근 할 수 있도록 getter()메서드를 설계하고, 전체 속성 접근을 위한 toString()을 오버라이딩 하였다.

또한 getAll()메서드를 추가해 배열에 있는 모든 인스턴스를 출력 및 줄바꿈 되도록 설계했다.

0개의 댓글