Java Collection - 제네릭(Generic)

강서진·2023년 11월 17일
0

Java

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

강좌 Course 2. Part 2. ch2 요약

제네릭

ArrayList는 Object[]을 사용하기 때문에 한 가지 타입의 객체만을 넣으려고 해도 다른 타입의 객체를 넣을 수 있어 안정성이 떨어진다.
이를 보완하기 위해 등장한 것이 제네릭으로, 자바에서 데이터타입을 일반화하는 방법이다. 제네릭을 사용하면 컬렉션, 메서드, 클래스 등에서 사용하는 데이터타입을 런타임 시에(=실행시) 결정할 수 있다. 제네릭을 사용하면 조금 더 안정적이고 유연하게 코드를 짤 수 있다.
또, 제네릭 타입을 선언할 때 어떤 데이터타입이 들어올지 정해져있지 않아 일반적인 메서드나 클래스를 작성할 수 있어 재사용성이 높아진다.
제네릭은 <> 기호를 사용하여 표시한다.

// 제네릭을 사용한 ObjectArr 클래스
public class ObjectArr<T> { // 제네릭으로 array 타입 미정
    private T[] array;
    private int size;

    public ObjectArr(int size) {
        array = (T[]) new Object[size]; // Object 배열로 받고 T[]로 다운캐스팅
    }

    public void set(int index, T value) {
        array[index] = value; 
        size++; // set 실행한 횟수가 size
    }

    public T get(int index) {
        return array[index];
    }

    public int size() {
        return size;
    }
}

ObjectArr에 String을 넣어보면, 잘 작동한다. 다른 객체도 가능하다.

public class GenericTest {
    public static void main(String[] args) {
        ObjectArr<String> arr = new ObjectArr<>(5);
        arr.set(0,"a");
        arr.set(1,"b");
        arr.set(2,"c");
        arr.set(3,"d");

        for (int i=0;i<arr.size();i++){
            System.out.println(arr.get(i));
        }

        System.out.println(arr.size());
    }
}

제네릭 멀티 타입 파라미터

자바 제네릭에서 멀티 타입 파라미터제네릭타입을 여러 개 선언하여 사용하는 것이다. 맵에서 key와 value를 사용하는 것처럼 2개 혹은 그 이상을 선언하여 받을 수 있다.
* K, V를 사용하는 것은 그저 convention일 뿐 다른 이름으로 설정하여도 된다.
사진에서 보듯 Pair에서 K, V로 받은 제네릭 멀티타입 파라미터를 PairGenericTest에서는 String과 Integer로 받을 수 있었다.

제네릭 제한된 타입 파라미터

제한된 타입 파라미터는 받을 수 있는 타입을 특정해둔 것으로, 제네릭 클래스나 메서드에서 사용할 수 있는 타입을 제한할 수 있다.
아래의 AverageCalculator에서 볼 수 있듯, 제네릭 타입 파라미터를 넘겨주는 부등호 안에 extends Number처럼 제네릭을 제한할 수 있다. Numbers를 상속한 타입만 받을 수 있다는 말로, String이나 다른 타입이 오면 컴파일 오류가 나게 된다.

public class AverageCalculator <T extends Number> {
    private T[] numbers;
    public AverageCalculator(T[] numbers){
        this.numbers=numbers;
    }
    public double calculateAvg(){
        double sum = 0.0;
        for(T num:numbers){
            sum += num.doubleValue();
        }
        return sum/ numbers.length;
    }
}

만든 AverageCalculator를 사용해보았다.
Integer와 Double을 넣으니 잘 돌아갔다.

public class GenericLimitTest {
    public static void main(String[] args) {
        Integer[] integers = {10,20,30,40,50};
        Double[] doubles = {1.0,2.0,3.0,4.0,5.0};

        AverageCalculator<Integer> intCal = new AverageCalculator<>(integers);
        AverageCalculator<Double> dblCal = new AverageCalculator<>(doubles);

        double intAvg = intCal.calculateAvg();
        double dblAvg = dblCal.calculateAvg();

        System.out.println(intAvg);
        System.out.println(dblAvg);
    }
}
post-custom-banner

0개의 댓글