늦은 프로그래밍 이야기

컬렉션, 제네릭스 본문

내일배움캠프/Java 기초

컬렉션, 제네릭스

한정규 2022. 11. 16. 21:52

컬렉션 (Collection)

 - 자바에서 자료구조를 표현하는 인터페이스.

 - 컬렉션 프레임워크 : 다수의 데이터를 다루기 위한 자료구조를 표현하고 사용하는 클래스의 집합.

 - 컬렉션 인터페이스 : 컬렉션 클래스에 저장된 데이터를 읽고, 추가하고, 삭제하는 등 데이터를 다루는 기본적인 메소드들을 정의.

 - 컬렉션 프레임워크를 구성하는 모든 클래스가 제네릭으로 표현(<E>, <K,V>)되어 있다.

주요 인터페이스 간의 상속 관계. 출처 : http://www.tcpschool.com/java/java_collectionFramework_concept

 

자료구조

 1) List : 순서가 있는 데이터의 집합. 데이터의 중복을 허용. (Vector, ArrayList, LinkedList, Stack, Queue)

 2) Set : 순서를 유지하지 않는 데이터의 집합. 데이터의 중복을 허용하지 않음. (HashSet, TreeSet)

 3) Map : 키와 값의 쌍으로 이루어진 데이터의 집합. 순서는 유지하지 않음. 키는 중복이 허용되지 않고 값은 중복을 허용. (HashMap, TreeMap, Hashtable, Properties)

 4) Stack : 마지막에 넣은 데이터를 먼저 꺼내는 자료구조. LIFO(Last In First Out). 후입선출

 5) Queue : 먼저 넣은 데이터를 먼저 꺼내는 자료구조. FIFO(First In First Out). 선입선출

 

리스트 (List)

 1) 생성

List<자료형> 변수명 = new ArrayList<>();

 

 2) 메소드

 - add(값) : 리스트에 입력한 순서대로 값을 입력한다.

 - Collection.sort() : 리스트를 오름차순으로 정렬한다.

 - remove(인덱스) : 인덱스에 해당하는 데이터를 제거한다.

 - size() : 리스트의 전체길이를 반환한다.

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Integer> integerList = new ArrayList<>();
        integerList.add(1);
        integerList.add(5);
        integerList.add(4);      // 리스트에 1개씩 입력
        integerList.add(11);
        integerList.add(10);

        System.out.println(integerList); // [1, 5, 4, 11, 10]

        Collections.sort(integerList);   // 리스트 정렬
        System.out.println(integerList); // [1, 4, 5, 10, 11]
        System.out.println(integerList.size()); // 5

        integerList.remove(4);           // 4번째 인덱스 제거
        System.out.println(integerList); // [1, 4, 5, 10]

        for(int i = 0; i < integerList.size(); i++) {  // .size() = 리스트 전체길이
            System.out.println(integerList.get(i));    // 리스트 내의 원소 반복 (for문)
        }
        for(int current: integerList) {
            System.out.println(current);   // 리스트 내의 원소 반복 (for-each문)
        }
    }
}

 

셋 (Set)

 - 오름차순으로 자동 정렬.

 1) 생성

Set<자료형> 변수명 = new HashSet<>();

 

 2) 메소드

 - add(값) : 셋에 입력한 순서에 상관 없이 추가한다.

 - remove(값) : 해당 값의 데이터를 제거한다.

 - removeAll() : ArrayList에 삽입한 데이터를 한번에 제거한다.

 - contains(값) : 해당 값의 유무를 True or False로 반환한다.

 - size() : Set의 길이를 반환한다.

 - clear() : Set에 저장되어 있는 데이터를 모두 제거한다.

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Main {
    public static void main(String[] args) {
        Set<Integer> integerSet = new HashSet<>();
        integerSet.add(1);
        integerSet.add(1);
        integerSet.add(3);
        integerSet.add(2);      // 1개씩 입력.
        integerSet.add(9);
        integerSet.add(8);
        System.out.println(integerSet); // [1, 2, 3, 8, 9]

        Set<String> stringSet = new HashSet<>();
        stringSet.add("LA");
        stringSet.add("New York");
        stringSet.add("LasVegas");
        stringSet.add("San Francisco");
        stringSet.add("Seoul");
        System.out.println(stringSet); // ["LA", "LasVegas", "New York", "San Francisco", "Seoul"]

        stringSet.remove("Seoul"); // 해당 값을 제거
        System.out.println(stringSet); // ["LA", "LasVegas", "New York", "San Francisco"]

        List<String> target = new ArrayList<>();
        target.add("New York");
        target.add("LasVegas");         // 제거할 데이터를 ArrayList에 삽입
        stringSet.removeAll(target);    // 삽입한 데이터를 한번에 삭제
        System.out.println(stringSet);  // ["LA", "San Francisco"]

        System.out.println("LA 포함되어있나요? " + stringSet.contains("LA"));  // True
        System.out.println("Seoul 포함되어있나요? " + stringSet.contains("Seoul")); // False

        System.out.println(stringSet.size());  // 2
        stringSet.clear();         // 모두 제거
        System.out.println(stringSet); // []
    }
}

 

맵 (Map)

 1) 생성

Map<Key자료형, Value자료형> 변수명 = new HashMap<>();

 

 2) 메소드

 - put(키, 밸류) : 키(Key)와 밸류(Value)를 입력한다.

 - get(키) : 해당 키의 밸류를 보여준다.

 - containsKey(키) : 해당 키값의 유무를 True or False로 반환한다.

 - containsValue(밸류) : 해당 밸류값의 유무를 True or False로 반환한다.

 - clear() : map의 데이터를 모두 제거한다.

import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        Map<Integer, String> map = new HashMap<>();
        map.put(1, "apple");
        map.put(2, "berry");
        map.put(3, "cherry");

        System.out.println(map);

        System.out.println("1st in map : " + map.get(1));

        map.remove(2);
        System.out.println(map);
        System.out.println(map.containsKey(2));
        System.out.println(map.containsValue("cherry"));

        map.clear();
        System.out.println(map);
    }
}

 

스택 (Stack)

 1) 생성

Stack<자료형> 변수명 = new Stack<>();

 

 2) 메소드

 - push(값) : Stack에 데이터를 입력.

 - peek() : 맨 마지막에 넣은 데이터를 보여준다. (제거되지 않음.)

 - pop() : 맨 마지막에 넣은 데이터를 꺼내어 반환한다. (제거됨.)

 - contains(값) : 해당 값의 유무를 True of False로 반환한다.

 - empty(), isEmpty() : 스택이 비어있는지 여부를 True of False로 반환한다.

 - clear() : 스택의 데이터를 모두 제거한다.

import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        stack.push(1);
        stack.push(3);
        stack.push(7);
        stack.push(5);
        System.out.println(stack);  // [1, 3, 7, 5]

        System.out.println(stack.peek());  // 5 (마지막에 입력한 데이터)
        System.out.println("size : " + stack.size());  // size : 5
        System.out.println(stack.pop());   // 5 (마지막에 입력한 데이터)
        System.out.println("size : " + stack.size());  // size : 4

        System.out.println(stack.contains(1));  // True
        System.out.println(stack.empty());  // False
        stack.clear();  // 모두 제거
        System.out.println(stack.isEmpty()); // True
    }
}

 

큐 (Queue)

 1) 생성

Queue<자료형> 변수명 = new LinkedList<>();

 

 2) 메소드

 - add(값) : Queue에 데이터를 입력.

 - poll() : 맨 처음 입력한 데이터를 꺼내어 반환한다. (제거됨)

 - peek() : 맨 처음 입력한 데이터를 보여준다. (제거되지 않음.)

 - isEmpty() : Queue가 비어있는지 여부를 True or False로 반환한다.

 - clear() : Queue의 데이터를 모두 제거한다.

import java.util.LinkedList;
import java.util.Queue;

public class Main {
    public static void main(String[] args) {
        Queue<Integer> queue = new LinkedList<>();
        queue.add(1);
        queue.add(5);
        queue.add(3);
        System.out.println(queue); // [1, 5, 3]
        System.out.println(queue.poll()); // 1
        System.out.println(queue); // [5, 3]
        System.out.println(queue.peek()); // 5
        System.out.println(queue); // [5, 3]
        System.out.println(queue.isEmpty()); // false
        queue.clear();
        System.out.println(queue.isEmpty()); // true

    }
}

 

어레이디큐 (ArrayDeque)

 - 양 끝에서 삽입과 삭제가 가능하다.

 

 1) 생성

ArrayDeque<자료형> 변수명 = new ArrayDeque<>();

 

 2) 메소드

 - addFirst(값) : 어레이디큐에 데이터를 앞으로 입력. (크기 문제가 생길때 Exception을 반환)

 - addLast(값) : 어레이디큐에 데이터를 뒤로 입력. (크기 문제가 생길때 Exception을 반환)

 - offerFirst(값) : 어레이디큐에 데이터를 앞으로 입력 (크기 문제가 생길때 False를 반환)

 - offerLast(값) : 어레이디큐에 데이터를 뒤로 입력. (크기 문제가 생길때 False를 반환)

 - push(값) : 데이터를 앞으로 입력.

 - pop() : 데이터를 앞에서 꺼내어 반환한다. (제거됨)

 - removeFirst(), removeLast() : 맨 앞, 맨 뒤의 데이터를 제거하고 반환한다.

 - pollFirst(), pollLast() : 맨 앞, 맨 뒤의 데이터를 꺼내어 반환한다. (제거됨)

 - peekFirst(), peekLast() : 맨 앞, 맨뒤의 데이터를 보여준다. (제거되지 않음.)

 - size() : 어레이디큐의 길이를 반환한다.

import java.util.ArrayDeque;

public class Main {
    public static void main(String[] args) {
        ArrayDeque<Integer> arrayDeque = new ArrayDeque<>();
        arrayDeque.addFirst(1);
        arrayDeque.addFirst(2);
        arrayDeque.addFirst(3);
        arrayDeque.addFirst(4);
        System.out.println(arrayDeque); // [4, 3, 2, 1]

        arrayDeque.addLast(0);
        System.out.println(arrayDeque); // [4, 3, 2, 1, 0]

        arrayDeque.offerFirst(10);
        System.out.println(arrayDeque); // [10, 4, 3, 2, 1, 0]
        arrayDeque.offerLast(-1);
        System.out.println(arrayDeque); // [10, 4, 3, 2, 1, 0, -1]

        arrayDeque.push(22);
        System.out.println(arrayDeque); // [22, 10, 4, 3, 2, 1, 0, -1]
        System.out.println(arrayDeque.pop()); // 22
        System.out.println(arrayDeque);  // [10, 4, 3, 2, 1, 0, -1]
        
        System.out.println(arrayDeque.removeFirst()); // 10
        System.out.println(arrayDeque.removeLast()); // -1
        System.out.println(arrayDeque);  // [4, 3, 2, 1, 0]
        System.out.println(arrayDeque.size()); // 5

        System.out.println(arrayDeque.peekFirst()); // 4
        System.out.println(arrayDeque); // [4, 3, 2, 1, 0]
        System.out.println(arrayDeque.size()); // 5
        
        System.out.println(arrayDeque.pollFirst()); // 4
        System.out.println(arrayDeque);  // [3, 2, 1, 0]
        System.out.println(arrayDeque.size()); // 4
        
        arrayDeque.clear();
        System.out.println(arrayDeque.isEmpty()); // true
    }
}

제네릭스 (Generics)

 - 데이터의 타입을 일반화(generalize)한다는 뜻.

 - 다양한 타입의 객체들을 다루는 메소드나 컬렉션 클래스의 컴파일 시의 타입체크를 해주는 기능

 - 객체의 타입을 컴파일 시에 미리 타입 검사를 하기 때문에 안정성이 높아진다.

 

선언

 - 클래스와 메소드에만 선언할 수 있다.

class MyArray<T> {
    T element;
    void setElement(T element) { 
    	this.element = element; 
    }
    T getElement() { 
    	return element; 
    }
}

 - 'T'를 타입 변수(type variable)라 하고, 임의의 참조형 타입을 의미.

 - 여러 개의 타입 변수는 쉼표(,)로 구분하여 명시.

 - 클래스뿐만 아니라 메소드의 매개변수나 반환값으로 사용.

 

생성

MyArray<Integer> myArr = new MyArray<Integer>();

MyArray<Integer> myArr = new MyArray<>(); // 타입을 추정할 수 있는경우 타입을 생략할 수 있다.

 - 클래스를 생성할 때 실제 타입을 명시하면, 내부적으로 정의된 타입변수가 명시된 실제 타입으로 변환되어 처리된다.

 - 타입변수 자리에 사용할 실제 타입을 명시할 때 기본 타입을 바로 사용할 수 없다.

 

타입인자 약어

 - <T> == Type

 - <E> == Element

 - <K> == Key

 - <V> == Value

 - <N> == Number

 - <R> == Result 리턴타입

 

제거시기

 - 자바 코드에서 선언되고 사용된 제네릭 타입은 컴파일 시 컴파일러에 의해 자동으로 검사되어 타입 변환된다.

 - 코드 내의 모든 제네릭 타입은 제거되어, 컴파일된 class 파일에는 어떠한 제네릭 타입도 포함되지 않게 된다.

 

제한

 - 제네릭은 'T'와 같은 타입변수를 사용하여 타입을 제한한다.

 - extends 키워드를 사용하여 타입변수에 특정 타입만을 사용하도록 제한할 수 있다.

 - 클래스 내부에서 사용된 모든 타입변수에 제한이 걸린다.

class AnimalList<T extends LandAnimal> {
    ... 
}

 - 인터페이스를 구현할 경우에도 implements 키워드가 아닌 extends 키워드를 사용해야 한다.

interface WarmBlood { 
    ... 
}

...

class AnimalList<T extends WarmBlood> { 
    ... 
}

 - 클래스와 인터페이스를 동시에 상속받고 구현해야 하면 엠퍼센트(&)를 사용하면 된다.

class AnimallList<T extends LandAnimal & WarmBlood> {
    ...
}

Comments