Java API(2)

강서진·2023년 11월 16일
0

Java

목록 보기
17/35
post-custom-banner

강좌 Course 2. Part 1. ch2 요약

배열처럼 동작하는 API

정수 5개를 배열에 저장하고 출력해보았다.

public class IntArrayBasic {
    public static void main(String[] args) {
        // 배열생성동작: 고정된 길이
        int[] nums = new int[5]; 
		
        // 저장동작
        nums[0] = 1;
        nums[1] = 2;
        nums[2] = 3;
        nums[3] = 4;
        nums[4] = 5;

		// .length: 배열의 길이를 구하는 동작
        for (int i=0;i<nums.length;i++){
        	// 데이터를 얻는 동작
            int data = nums[i];
            System.out.println(data);
        }
    }
}

배열 생성, 요소 저장, 길이를 구하고 데이터를 가져오는 총 4가지 동작을 사용하고 있다.
이 기능들을 직접 구현해보았다.

public class IntArray {
    // 초기 배열 크기 상수, 수정 불가
    private static final int DEFAULT_CAPACITY = 5;
    private int[] elements;
    private int size = 0;

    // 생성동작
    public IntArray() {
        elements = new int[DEFAULT_CAPACITY];
    }
    // 저장하는 동작
    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);
    }
    // 가져오는 동작
    public int get(int index){
        if (index<0||index>=size){
            // 예외클래스 생성
            throw new IndexOutOfBoundsException("Index out of bounds");
        }
        return elements[index];
    }
    // 크기를 구하는 동작
    public int size(){
        return size;
    }
}
public class MyIntArray {
    public static void main(String[] args) {
        IntArray list = new IntArray();

        list.add(1);
        list.add(2);
        list.add(3);

        System.out.println(list.get(0));
        System.out.println(list.get(1));
        System.out.println(list.get(2));

        System.out.println("size="+list.size());
    }
}

이 IntArray를 그대로 사용하되 int를 미리 생성해둔 Book 클래스로 바꿔 배열을 동작시킬 수도 있다.
더 나아가 객체배열을 받을 때 Object배열로 받으면 어떤 객체라도 저장이 가능해진다.

public class ObjectArray {
    private static final int DEFAULT_CAPACITY=5;
    private Object[] elements;
    private int size = 0;

    // 원하는 크기의 배열 생성
    public ObjectArray(int capacity){
        elements = new Object[capacity];
    }
    // 기본생성자
    public ObjectArray() {
        this(5); // this: 생성자 안에서 다른 생성자를 호출할 때 사용한다.
    }
    // 저장하는 동작
    public void add(Object element){
        if (size==elements.length){
            ensureCapacity();
        }
        elements[size++]=element;
    }
    // 배열에 자리가 더 없으면 공간 추가, 기존 배열 내용 복사
    private void ensureCapacity(){
        int newCapacity = elements.length*2;
        elements = Arrays.copyOf(elements, newCapacity);
    }
    // 가져오는 동작
    public Object get(int index){
        if (index<0||index>=size){
            // 예외클래스 생성
            throw new IndexOutOfBoundsException("Index out of bounds");
        }
        return elements[index];
    }
    // 크기를 구하는 동작
    public int size(){
        return size;
    }
}

display()라는 메서드를 가진 A, B, C 클래스를 생성하여 ObjectArray에 저장하였다. Object를 받을 경우, 자식클래스들의 메서드를 사용하려면 downcasting을 거쳐야 한다.

public class MyObjectArrayTest {
    public static void main(String[] args) {
        ObjectArray obj = new ObjectArray();

        // Object element = new A(); --> upcasting
        obj.add(new A());
        obj.add(new B());
        obj.add(new C());

        // downcasting is necessary
        A a = (A)obj.get(0);
        a.display();

        B b = (B)obj.get(1);
        b.display();

        C c = (C)obj.get(2);
        c.display();
    }
}

이러한 기능들이 더 잘 구현되어 있는 것이 자바에서 제공하는 ArrayList라는 클래스이다. java.util 패키지 안에 들어있고, 생성, 저장, 반환 및 배열크기를 재는 등의 동작뿐만 아니라 다른 기능들도 포함하고 있다. 자세한 사항은 오라클 사이트의 document를 참고하면 된다.

import fc.java.c2.model.*;

import java.util.ArrayList;

public class ArrayListTest {
    public static void main(String[] args) {
        // Book 3권을 배열에 저장하고 출력

        // 기본크기 10, 크기 입력시 그 크기로 생성(도큐먼트 참고)
        ArrayList list = new ArrayList(1);
        list.add(new Book("Java",15000, "ABC","AAA"));
        list.add(new Book("Java2",16000,"ABC","BBB"));
        list.add(new Book("Java3",17000,"ABC","CCC"));

        for(int i = 0;i<list.size();i++){
            Book b = (Book)list.get(i);
            // Book의 toString() 자동 호출
            System.out.println(b);

            // Object, 객체 print하면 자동으로 toString() 호출
            // 재정의 되어 있어서 자동으로 Book의 toString() 실행
            System.out.println(list.get(i));
        }
    }
}

기본적인 배열은 길이가 고정되어있어 불편하나, ArrayList같은 API는 길이를 늘리는 기능이 추가되어 있어 편리하다. 위 코드에서 처음에는 배열의 길이를 1개로 설정하고, 그 뒤로 2개의 Book 객체를 더 추가하였으나 오류가 나지 않았다. 추가로 2개를 더 저장하고자 배열의 크기가 늘어난 것이다.
* ArrayList가 아닌 List에 받아도 된다.

만약 서로 같은 종류의 객체를 여러개 저장하는 경우라면, List뒤에 <자료형>을 추가함으로써 조금 더 안정적으로 ArrayList를 사용할 수 있다(제네릭이라고 한다).

List<Book> list = new ArrayList<Book>(1);

이렇게 ArrayList에 Book 객체만으로 제한을 걸어주면, 다른 타입의 객체는 배열에 넣을 수 없다. 제네릭을 사용하면 Object[] 가 아니라 해당 자료형[] 이 생성되어 업캐스팅이나 다운캐스팅을 해줄 필요가 없어 코드가 훨씬 간편해진다.

public class ArrayListBestTest {
    public static void main(String[] args) {
        
        List<Book> list = new ArrayList<Book>(1);
        list.add(new Book("Java", 15000, "ABC", "AAA"));
        list.add(new Book("Java2", 16000, "ABC", "BBB"));
        list.add(new Book("Java3", 17000, "ABC", "CCC"));

        for (int i = 0; i < list.size(); i++) {
            Book b = list.get(i);
            System.out.println(b);
            
        }
    }
}
post-custom-banner

0개의 댓글