코드스테이츠 백엔드 17일차 | 컬렉션

hyoreal·2022년 7월 14일
0

CodeStates

목록 보기
18/32

어제부로 객체지향 프로그래밍을 마치고 컬렉션에 들어간다. 그동안 클래스내부 코드를 쓸때 걱 타입마다 지정하여 선언하고 했었는데 컬렉션의 제네릭에서는 그럴 필요가 줄어든다고 해서 굉장히 획기적이라고 느꼈다. 제네릭을 배우고 나면 코딩이 한결 쉬워지겠지?! 이번 수업도 너무 기대된다!!!


제네릭

학습목표
1.제네릭의 장점
2.제네릭 클래스 정의 및 활용
3.제네릭 메서드 정의 및 활용

  • 제네릭 의미 : 일반적인.

  • 자바에서의 제네릭 의미 : 타입을 추후에 지정할 수 있고 특정 데이터타입에 묶여있지 않게 일반화한것.

  • 제네릭의 장점?

    • 객체 타입 안정성 높임
    • 반환값 타입 변환 및 타입 검사에 들어가는 노력 줄여줌.
class Basket<T> { // T는 타입 매개변수. 참조형 타입.

    private T item;

    public Basket(T item) {
        this.item = item;
    }

    public T getItem() {
        return item;
    }

    public void setItem(T item) {
        this.item = item;
    }
}
public class BasketTest {
    public static void main(String[] args){
        Basket<String> basket1 = new Basket<String>("Hello"); 
        Basket<Integer> basket2 = new Basket<Integer>(1);
        Basket<Boolean> basket3 = new Basket<Boolean>(true);
        Basket<Double> basket4 = new Basket<Double>(3.14);
        // 타입변수 자리에 실제 타입 명시할때 래퍼클래스 사용!
        // 생성하는 인스턴스마다 타입 지정.
        // Basket<Double> basket4 = new Basket<>(3.14);
        // 이 코드와 같이 구체적인 타입 생략 가능.

        System.out.println(basket1.getItem());
        System.out.println(basket2.getItem());
        System.out.println(basket3.getItem());
        System.out.println(basket4.getItem());
    }
}

출력결과
> Hello
> 1 
> true
> 3.14
  • 타입 매개변수는 임의의 문자로 지정

  • T , K , V , E , N , R 자주사용

  • 각각 Type, Key, Value, Element, Number, Result의 첫글자.

  • 주의❗ 클래스변수에서는 타입매개변수 사용 불가!

  • 이유? 클래스 변수는 모든 인스턴스가 공유하는 변수인데 클래스변수에서 타입매개변수를 사용하게되면 클래스 변수 타입이 인스턴스마다 변하게됨. 즉, 같은 변수를 공유하는게 아니게 됨.

  • 제네릭 클래스를 사용할때 생성하는 인스턴스별로 타입을 지정해주어야함.

  • 제네릭 클래스에 다형성 적용 가능

class Flower { ... }
class Rose extends Flower { ... }
class RosePasta { ... }

//제네릭 클래스 정의
class Basket<T> {
    private T item;

    public T getItem() {
        return item;
    }

    public void setItem(T item) {
        this.item = item;
    }
}

//인스턴스화
public static void main(String[] args) {
		Basket<Flower> flowerBasket = new Basket<>();
		flowerBasket.setItem(new Rose());      // 다형성 적용
		flowerBasket.setItem(new RosePasta()); // 에러
}
  • RosePasta는 Flower로부터 상속되지 않았기에 에러발생.

  • 제네릭 클래스에 다형성을 적용하여 그 어떤 타입도 지정가능.

  • 제네릭클래스를 정의할때

class Basket <T extends Flower>

이와 같이 정의하면 Flower의 하위 클래스만 타입으로 받음.

  • 뿐만 아니라 특정 인터페이스를 구현한 클래스만 타입으로도 받을 수 있음.
class Basket<T extends Plant>
  • 특정 클래스를 상속받으면서 특정 인터페이스를 구현한 클래스만 타입으로도 받을수있음.
  class Basket <T extends Plant & Flower>
  • 래퍼클래스 : 기본타입 데이터를 객체로 포장해준다.
  • 래퍼클래스는 인스턴스에 저장된 값 변경 불가.
  • 값을 참조하기 위해 새로운 인스턴스를 생성하고 생성된 인스턴스 값만 참조.

제네릭 메서드

  • 제네릭 메서드 : 클래스 내부에서의 특정 메서드만 제네릭으로 선언한 것.
class Basket<T> { // 여기 선언된 T와
      ...
      public <T> void add(T element){ //여기선언된 T는 서로 다른 매개변수로 간주.
  }
}
  • 제네릭 메서드의 타입 지정은 메서드가 호출될 때 지정.
  Basket<String> basket = new Basket<>(); //class의 T가 String
  basket.<Integer>add(10); // 메서드의 T가 Integer
  basket.add(10);
  • 메서드 타입 매개변수는 static메서드에서도 선언 가능.
  • 단 타입이 지정되기 전 이므로 String클래스 메서드 사용 불가.
  • Object클래스 메서드는 사용가능.
    • 이유? 모든 클래스는 Object의 하위 클래스이기 때문.

지금까지 공부한것중에 가장 오랜 이해가 걸렸다. 생각보다 이해가 잘 안가서 많은 정보들을 찾아본것같다. 분명 엔지니어님께서 말씀하시기로는 다음 학습인 컬렉션 프레임워크가 힘들꺼라하셨는데 걱정이 많아지네...


컬렉션 프레임워크

학습목표
1.컬렉션 프레임워크의 핵심 인터페이스 이해 및 사용
2.주요 인터페이스와 컬렉션클래스의 핵심 메서드 사용
3.필요에 따라 어떤 인터페이스와 컬렉션클래스를 사용하는게 적합한지

  • 컬렉션 : 여러 데이터들의 집합.
  • 컬렉션 프레임워크 : 컬렉션을 다루는데 있어 편리한 메서드를 정의해놓은것.
  • 컬렉션 프레임워크는 주요 인터페이스로 List,Set,Map 제공.

  • List

    • 데이터 순서 유지
    • 중복저장 가능 컬렉션 구현
    • ArrayList, Vector, Stack, LinkedList 등
  • Set

    • 데이터 순서 유지X
    • 중복저장 불가
    • HashSet, TreeSet 등
  • Map

    • key(키),value(값)을 쌍으로 데이터 저장 컬렉션 구현
    • 데이터 순서 유지X
    • 키는 중복저장 불가. 값은 중복저장 가능
    • HashMAp,HashTable,TreeMap,Properties 등
  • Collection : List와 Set의 공통점이 추출되어 추상화시킨것.

Collection 인터페이스

  • 인터페이스 메서드

    • add(Object o) / addAll(Collection c) : 객체 및 컬렉션 객체들을 컬렉션에 추가. 리턴타입 boolean

    • contains(Object o) / containsAll(Collection c) : 객체 및 컬렉션 저장 여부 리턴. 리턴타입 boolean

    • Iterator() : 컬렉션의 iterator을 리턴. 리턴타입 iterator

    • equals(Object o) : 컬렉션 동일 여부 확인. 리턴타입 boolean

    • isEmpty() : 컬렉션 비어있는지 여부 확인. 리턴타입 boolean

    • size() : 저장된 전체 객체 수 리턴. 리턴타입 int

    • clear() : 컬렉션에 저장된 모든 객체 삭제. 리턴타입 void

    • remove(Object o) / removeAll(Collection c) : 객체 및 컬렉션 삭제 후 성공여부 리턴. 리턴타입 boolean

    • retainAll(Collection c) : 주어진 컬렉션 제외, 모든 객체를 컬렉션에서 삭제 및 컬렉션 변화 여부 리턴. 리턴타입 boolean

    • toArray() : 컬렉션에 저장된 객체를 객체배열로 반환. 리턴타입 Object[]

    • toArray(Object[] a) : 배열에 컬렉션의 객체 저장 후 반환. 리턴타입 Object[]

List

  • List인터페이스는 객체를 일렬로 늘어놓은 구조.

  • 인덱스로 객체 관리.

  • 인덱스로 객체 검색,추가,삭제 등 기능 제공

  • List 인터페이스 메서드

    • add(int index, Object element) : 인덱스에 객체 추가. 리턴타입 void

    • addAll(int index, Collection c) : 인덱스에 컬렉션 추가. 리턴타입 boolean

    • set(int index, Object element) : 인덱스위치에 객체추가. 리턴타입 Object

    • get(int index) : 인덱스에 저장된 객체 반환. 리턴타입 Object

    • indexOf(Object o) / lastIndexOf(Object o) : 순방향 / 역방향으로 탐색 후 주어진 객체 위치 반환. 리턴타입 int

    • listIterator() / listIterator(int index) : List의 객체 탐색하는 ListIterator 반환/ 주어진 인덱스부터 탐색할 수 있는 ListIterator 반환. 린턴타입 ListIterator

    • subList(int fromIndex, int toIndex) : from ~ to 까지의 인덱스에 있는 객체 반환. 리턴타입 List

    • remove(int index) : 인덱스에 저장된 객체 삭제 및 삭제한 객체 반환. 리턴타입 Object

    • remove(Object o) : 객체 삭제. 리턴타입 boolean

    • sort(Comparator c) : 비교자(comparator)로 list 정렬. 리턴타입 void

  • List 인터페이스 구현 클래스로는 ArrayList,Vector,LinkedList,Stack 등

  • ArrayList, LinkedList 가 가장 많이 사용

  • ArrayList : 기능은 Vector와 동일하지만 그보다 개선.

  • ArrayList에 객체를 추가하면 인덱스로 관리되고 저장용량 초과되면 자동으로 용량이 늘어남. 데이터 연속적 구성.

ArrayList 메서드

  • 컬렉션 프레임워크 사용시 소스코드 최상당 패키기 밑에 import해야함.

  • LinkedList : 데이터를 효율적으로 추가, 삭제, 변경하기 위해 사용.

  • ArrayList와 LinkedList의 차이

    • ArrayList는 순차적으로 데이터를 추가,삭제,변경 하거나 데이터를 읽을때 유용

    • 하지만 중간에 데이터를 추가하거나 삭제하기에는 번거로움.

    • LinkedList는 중간에 데이터를 추가,삭제,변경하기에 유용

    • 즉 데이터에 잦은 변경이 있을땐 LinkedList, 데이터의 개수가 변하지 않을땐 ArrayList가 유용하다.

Iterator

  • List인터페이스에서 인덱스로 객체를 검색, 추가, 삭제할 수 있는 기능을 제공.

    • 이 기능이 Iterator 인터페이스에 정의돼있음.
  • Collection 인터페이스에서는 Iterator인터페이스를 구현한 클래스의 인스턴스를 반환하는 메서드인 iterator()가 정의돼있음.

    • 즉, Collection인터페이스에 정의된 iterator()를 호출하면 Iterator타입 인스턴스 반환.
  • Iterator 메서드

    • hasNext() : 읽어올 객체가 있으면 true, 없으면 false 리턴

    • next() : 컬렉션의 하나의 객체를 읽음. next()를 사용하기 전에 hasNext()로 읽어올 요소 있는지 확인해야함

    • remove() : next()로 읽어온 객체 삭제. next()호출한 다음에 remove()호출.

Set < E >

  • Set은 요소의 중복을 허용하지않고, 저장 순서를 유지하는 컬렉션.

    • 대표적인 Set을 구현한 클래스에는 HashSet, TreeSet이 있음
  • Set 메서드

    • add(Object o) : 객체 추가, 성공하면 true 실패하면 false반환. 리턴타입 boolean

    • contains(Object o) : 객체가 Set에 존재하는지 확인. 리턴타입 boolean

    • isEmpty() : Set이 비어있는지 확인. 리턴타입 boolean

    • Iterator() : 저장된 객체를 하나씩 반환하는 반복자 리턴. 리턴타입 Iterator

    • size() : 저장된 전체 객체의 수를 리턴. 리턴타입 int

    • clear() : Set에 저장된 모든 객체 삭제. 리턴타입 void

    • remove(Object o) : 객체 삭제. 리턴타입 boolean

  • HashSet : Set인터페이스를 구현한 가장 대표적 컬렉션.

    • HashSet에 값 추가할때 중복값인지 판단 순서

      1. add(Object o)를 통해 객체의 값을 저장하고자 함

      2. 저장하고자하는 객체의 해시코드를 hashCode()메서드로 얻어냄

      3. Set이 저장하고있는 모든 객체의 해시코드를 hashCode()로 얻어냄

      4. 저장하고자하는 객체의 해시코드, Set에 이미 저장돼있는 객체들의 해시코드 비교

        4-1. 같은 해시코드를 가진 객체가 존재하면 저장하고자했던 객체가 중복객체로 간주되어 Set에 추가X.add(Object o)가 true를 리턴.

        4-2. 같은 해시코드를 가진 객체가 존재하지 않으면 Set에 저장하고자했던 객체가 추가되고 add(Object o)가 false를 반환

      5. equals() 메서드로 객체 비교

        5-1. true가 리턴되면 중복객체로 간주, Set에 추가X, add(Object o)가 true 반환

        5-2. false가 리턴되면 Set에 객체 추가, add(Object o)가 false 반환

public class HashSetTest {
    public static void main(String[] args) {

        //HashSet 생성
        HashSet<String> lang = new HashSet<String>();

        //HashSet 에 객체 추가
        lang.add("Java");
        lang.add("Python");
        lang.add("JavaScript");
        lang.add("C++");
        lang.add("Kotlin");
        lang.add("Ruby");
        lang.add("Java"); //중복

        //반복자 생성하여 it에 할당
        Iterator it = lang.iterator();

        //반복자를 통해 HashSet을 순회하며 각 요소들을 출력
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
}

출력
Java
C++
JavaScript
Ruby
Python
Kotlin
  • 출력순서도 뒤죽박죽이고 중복되는 Java는 추가되지않음

  • TreeSet

  • TreeSet은 이진탐색트리형태로 데이터 저장.

  • 중복저장X,저장순서 바뀌는 Set인터페이스의 특징은 그대로임.

  • 이진탐색트리의 최상위 노드는 루트 라고 함.

  • 모든 왼쪽자식의 값이 루트나 부모보다 작고, 모든 오른쪽 자식의 값이 루트나 부모보다 크다는 특징.

  • TreeSet 메서드
    TreeSet메서드

  • Map < K, V >
  • Map : Key는 중복저장 불가, Value는 중복저장 가능.

  • Map 인터페이스 구현 클래스는 HashMap, Hashtable, TreeMap, SortedMap 등

  • Map 메서드

    • put(Object key, Object value) : 키로 값 저장. 키가 새로운 키일경우 null, 동일한 키가 있을경우 원래 있던 값을 새로운 값으로 대체 후 원래 있던 값 리턴. 리턴타입 Object
    • containsKey(Object key) : 주어진키가 있으면 true, 없으면 false 리턴. 리턴타입 boolean
    • containsValue(Object value) : 주어진 값이 있으면 true, 없으면 false 리턴. 리턴타입 boolean
    • entrySet() : 키와 값이 쌍으로 구성된 모든 Map.Entry객체를 Set에 담아서 리턴. 리턴타입 Set
    • get(Object key) : 주어진 키에 해당하는 값을 리턴. 리턴타입 Object
    • isEmpty() : 컬렉션이 비어있는지 확인. 리턴타입 boolean
    • keySet() : 모든 키를 Set 객체에 담아서 리턴. 리턴타입 Set
    • size() : 저장된 Entry객체의 총 개수 리턴. 리턴타입 int
    • values() : 저장된 모든 값을 Collection에 담아서 리턴. 리턴타입 Collection
    • clear() : 모든 Map.Entry(키,값)을 삭제. 리턴타입 void
    • remove(Object key) : 주어진 키와 일치하는 Map.Entry 삭제 후 값 리턴. 리턴타입 Object
  • HashMap

  • HashMap : Map인터페이스 구현 대표 클래스. 키,값으로 구성된 Entry객체 저장

  • 많은 양의 데이터를 검색하는데 유용

  • HashTable

  • HashTable은 HashMap과 내부구조 동일.


.....내용이 삼천만개... 오늘 할 내용이 너무 많은데 아직도 이해를 다 못했다. 내일 당장 페어프로그래밍으로 문제들을 풀어야하는데 눈앞이 캄캄하다ㅜㅜ
사실 처음에 제네릭부터 이해하는데 한참 걸렸다.
이해가 아예 안되는걸 열심히 구글링하며 정보를 찾고 또 고민해보고 코드를 작성해보며 조금씩 이해하게된것같다.
컬렉션은 뭐... 손톱만 살짝 담군 느낌..?
오늘은 아무래도 밤을 새야할것같다.
아무리 어려운 내용이어도 코딩은 너무 재미써...!!!!!
너무 재밌기에 어려워도 포기하고싶은 마음은 눈꼽만큼도 들지 않는다. 열심히 잘 해봐야지!!!!

profile
좌충우돌 코린이 성장기

0개의 댓글