본문 바로가기
개발/Java

제네릭(Generic)

by BellOne4222 2024. 1. 29.

제네릭(Generic)


제네릭을 사용해야하는 이유

  • Generic

    • 데이터 타입을 일반화 하는 방법
    • 컬렉션 , 메서드, 클래스 등에서 사용하는 데이터 타입을 런타임 시에 결정 할 수 있다.
  • 코드의 재사용성, 유연성이 높아진다.

    • 제네릭 타입을 선언할 때 어떤 데이터 타입이 들어올지 결정하지 않으므로, 다양한 데이터 타입에 대해 일반적으로 적용할 수 있는 메서드나 클래스를 작성할 수 있기 때문입니다.
public class ObjectArr<T> { // <T>는 가변 타입 나중에 재정의로 타입 결정
    private T[] array;
    private int size;

    public ObjectArr(int size){
        array = (T[])new Object[size]; // 어떤 타입이 올지 모르기 때문에 일단 T[] 타입으로 캐스팅해서 생성
    }

    public void set(int index, T value){
        array[index] = value;
        size++;
    }

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

    public int size(){
        return size;
    }
}
public class GenericTest {
    public static void main(String[] args) {
       /* ObjectArr<String> array=new ObjectArr<>(5);
        array.set(0, "Hello");
        array.set(1, "World");
        array.set(2, "Java");
        array.set(3, "Generic");

        for(int i=0;i<array.size();i++){
            System.out.println(array.get(i));
        }*/
        ObjectArr<Movie> bList=new ObjectArr<>(5);
        bList.set(0, new Movie("괴물","봉준호","2006", "한국"));
        bList.set(1, new Movie("기생충","봉준호","2019", "한국"));
        bList.set(2, new Movie("완벽한 타인","이재규","2018", "한국"));

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

    }
}

제네릭 타입이란?

  • 클래스, 인터페이스, 메소드 등에서 사용될 수 있는 타입 매개변수(Parameter)
  • 한 데이터타입만 지정하기 때문에 타입 안정성이 보장된다.
public class ArrayListGeneric {
    public static void main(String[] args) {
        List<Movie> list=new ArrayList<>(); // Movie[]
        list.add(new Movie("괴물","봉준호","2006", "한국"));
        //list.add("Hello"); // X -> Movie 타입으로 선언했기 때문에 타입 안전성을 보장 가능
        list.add(new Movie("기생충","봉준호","2019", "한국"));
        System.out.println(list.get(0));
        System.out.println(list.get(1));
    }
}

제네릭 멀티 타입 파라미터

  • 제네릭 타입을 여러개 선언하여 사용
// 유연성, 재사용성, 타입의 안전성 보장
public class Pair<K,V> {
    private K key;
    private V value;

    public Pair() {
    }

    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public K getKey() {
        return key;
    }

    public void setKey(K key) {
        this.key = key;
    }

    public V getValue() {
        return value;
    }

    public void setValue(V value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Pair{" +
            "key=" + key +
            ", value=" + value +
            '}';
    }

public class PairGenericTest {
    public static void main(String[] args) {
        Pair<String, Integer> pair = new Pair<>("hello", 1);
        System.out.println(pair.getKey());
        System.out.println(pair.getValue());

        // 검색을 빠르게 할수있는 자료구조(HashMap, Hashtable)
        Map<String, Integer> maps = new HashMap<>();
        maps.put("kor", 60);
        maps.put("eng", 80);
        maps.put("math", 70);

        System.out.println(maps.get("kor")); // 60
        System.out.println(maps.get("eng")); // 80
        System.out.println(maps.get("math")); // 70

    }
}

제한된 타입 파라미터

  • 특정한 타입으로 제한된 제네릭 타입 파라미터
  • 제네릭 클래스나 메서드에서 사용할 수 있는 타입을 제한 할 수 있다.
public class GenericLimitTest {
    public static void main(String[] args) {
        Integer[] integers = {1, 2, 3, 4, 5};
        Double[] doubles={1.0,2.0,3.0,4.0,5.0};

        // AverageCalculator에 오는 타입을 제한 할 수 있다.
        AverageCalculator<Integer> integerCalculator = new AverageCalculator<>(integers);
        double integerAverage = integerCalculator.calculateAverage();
        System.out.println(integerAverage);

        AverageCalculator<Double> doubleCalculator=new AverageCalculator<>(doubles);
        double doubleAverage=doubleCalculator.calculateAverage();
        System.out.println(doubleAverage); // 3.0
    }
}
public class AverageCalculator<T extends Number> {
    private T[] numbers; // Number를 상속하여서 Number의 타입밖에 올 수 없다.

    public AverageCalculator(T[] numbers){
        this.numbers = numbers;
    }

    public double calculateAverage() {
        double sum = 0.0;
        for(T number : numbers){
            sum += number.doubleValue();
        }

        return sum / numbers.length;
    }
}

'개발 > Java' 카테고리의 다른 글

API 활용  (0) 2024.01.29
Collection Framework API  (1) 2024.01.29
Collection API  (0) 2024.01.29
인터페이스 기반의 프로그래밍  (0) 2024.01.29
자바 String 클래스  (1) 2024.01.29