백엔드 부트캠프/TIL

[TIL] DAY-16~17 제네릭과 컬렉션

o_b:us 2022. 5. 20. 18:01

제네릭(Generic)이란

변수를 선언할 때 모든 변수에는 자료형이 있습니다. 대부분 하나의 자료형으로 구현되지만, 필요에 따라 여러 자료형으로 만들 수 있다면 훨씬 유연하게 사용할 수 있습니다. 이와 같이 어떤 값이 하나의 참조 자료형이 아닌 여러 참조 자료형을 사용할 수 있도록 프로그래밍 하는것을 '제네릭(Generic) 프로그래밍이라고 합니다.

출처: 박은종 - 「Do it 자바 프로그래밍 입문」, 이지스 퍼블리싱


제네릭의 필요성

public class Cup{
    private Americano coffee;
    public void setCoffee(Americano coffee){
        this.coffee = coffee;
    }

    public Americano getCoffee() {
        return coffee;
    }
}
public class Cup{
    private Latte coffee;
    public void setCoffee(Latte coffee){
        this.coffee = coffee;
    }

    public Latte getCoffee() {
        return coffee;
    }
    }

위의 두 코드를 비교하자면 컵에 담긴 커피만 바뀌었을 뿐 기능적으로는 동일합니다.
Object는 모든 클래스의 최상위 클래스이므로 모든 클래스는 Object로 변환할 수 있습니다. <- 이 특성을 이용하면 굳이 별개의 set,get함수를 둘 필요가 없습니다.




아래의 예제를 보면

public class Cup{
    private Object coffee;
    public void setCoffee(Object coffee){
        this.coffee = coffee;
    }

    public Object getCoffee() {
        return coffee;
    }
}

이처럼 최상위 클래스인 Object를 자료형으로해서 coffee를 선언하였습니다.
이제 한번 Cup에 담아보겠습니다!

public class Main{
  public static void main(String[] args){
    Cup cup = new Cup();

    Americano drink1 = new Americano();
    cup.setCoffee(drink1);
    //업 캐스팅에 해당되죠? 그러므로 자동 형 변환이 이루어집니다.

    Americano drink2 = (Americano)cup.getCoffee();
    //getMaterial의 반환형은 Object이므로 Americano의 자료형에 맞게 다운캐스팅을 해주어야합니다.
  }
}

이 처럼 같은 자료형(Americano)인데도 Object를 이용하여 구현을 하면 매번 형 변환을 시켜줘야합니다. 정말 귀찮은 일이죠. 이래서 자바 v1.5 이후로 제네릭이 등장합니다. 이번엔 한번 제네릭 클래스로 바꿔보도록 하겠습니다.

public class GenericCup<T>{
  private T coffee;

  public void setCoffee(T coffee){
    this.coffee = coffee;
  }

  public T getCoffee(){
    return coffee;
  }
}

public class Main{
  public static void main(String[] args){
    GenericCup<Americano> cup = new GenericCup<Americano>();

    Americano drink1 = new Americano();
    cup.setCoffee(drink1);

    Americano drink2 = cup.getCoffee(); 
  }
}
자바7부터는 다이아몬드 연산자<>
GenericCup<Americano> cup = new GenericCup<Americano>();
를
GenericCup<Americano> cup = new GenericCup<>(); 
로 표기 할 수 있습니다.

컬렉션 프레임워크란 ?


Collection 인터페이스와 Map 인터페이스

Collection 인터페이스


다같은 컬렉션인줄 알았는데 Collections 프레임워크는 Collection 인터페이스와 Map 인터페이스 구조 기반으로 이루어져 있다는걸 알았다.

List 인터페이스와 Set 인터페이스

분류 구현한 클래스
List 인터페이스 ArrayList, Vector, LinkedList, Stack, Queue 등
Set 인터페이스 HashSet, TreeSet 등



주로 사용하는 메서드

메서드 설명
boolean add(E e) Collection에 객체를 추가
void clear() Collection에 모든 객체 제거
Iteraotr iterator Collection을 순환할 iterator 생성
boolean remove(Object o) Collection에 매개변수에 해당하는 인스턴스가 존재하면 제거
int size() Collection에 있는 요소의 개수 반환

List 자료구조는 중복으로 데이터가 들어갈 수 있지만, Set은 중복을 허용하지 않는다.

Map 인터페이스


주로 사용하는 메서드

메서드 설명
V put(K key, V value) key에 해당하는 value값을 map에 넣는다.
V get(K key) key에 해당하는 값인 value를 반환한다.
boolean isEmpty() Map이 비어있는가를 확인
boolean containskey(Object key) Map에 해당key가 있는지 여부를 확인한다.
boolean containsValue(Object value) Map에 해당 value가 있는지 여부를 확인한다.
Set keyset() key 집합을 Set으로 반환합니다.(Map의 key값은 중복X)
Collection values() value를 Collection으로 반환합니다(중복 무관)
V remove(key) key가 있는 경우 삭제한다.
boolean remove(Object key, Object value) key가 있는 경우 해당 value 또한 매개변수와 일치한지 확인하고 삭제한다.

Map 자료구조는 key, value인 쌍으로 이루어져 있다. 자료를 쌍으로 관리하여 사용할 때 편하다.

자료구조는 많이 글로만 봐서는 이해하는데 문제가 없다 다만, 실습을 해보지 않는다면 정확히 어떻게 사용해야할지 모를 수 있다. 그렇기 때문에 자료구조에 대해 잘 이해하곳 싶다면 다양한 문제를 직접 풀어보는 것을 추천한다.