본문 바로가기
IT

[Do it! 자바 프로그래밍 입문] 12 컬렉션 프레임워크

by csongin 2022. 6. 8.
728x90
반응형
제네릭(Generic)
컬렉션 프레임워크

제네릭(Generic)

제네릭(Generic) 프로그래밍

변수의 선언이나 메서드의 매개변수를 하나의 참조 자료형이 아닌 여러 자료형을 변환될 수 있도록 프로그래밍하는 방식

실제 사용되는 참조 자료형으로의 변환은 컴파일러가 검증하므로 안정적인 프로그래밍 방식

컬렉션 프레임워크에서 많이 사용되고 있음

 

제네릭(Generic) 클래스 정의 하기

여러 참조 자료형으로 대체 될 수 있는 부분을 하나의 문자로 표현

이 문자를 자료형 매개변수라고 함

public class GenericPrinter<T> { // 제네릭 클래스, <T> type의 약자, 자료형 매개변수
    private T material; 
    
    public void setMaterial(T material) {
        this.material = material;
    }
    
    public T getMaterial() {
        return material;
    }
}

자료형 매개변수 T

type의 의미로 T를 많이 사용함

<T>에서 <>는 다이아몬드 연산자라고 함

static 키워드는 T에 사용할 수 없음

ArrayList<String> list = new ArrayList<String>();
var list = new ArrayList<String>(); // 다이아몬드 연산자 내부에서 자료형은 생략 가능함
// 제네릭에서 자료형 추론(자바 10부터)

 

 

제네릭 클래스 사용하기

GenericPrinter<Powder> powderPrinter = new GenericPrinter<Powder>();
powderPrinter.setMatrial(new Powder());
Powder powder = powderPrinter.getMatrial(); // 명시적 형 변환을 하지 않음

T로 정의한 부분에 사용할 참조 자료형을 넣어서 클래스 생성
getMatrial() 메서드가 호출될 때 따라 강제 형 변환을 하지 않아도 됨

용어 설명
GenericPrinter<Powder> 제네릭 자료형(Generic type),
매개변수화된 자료형(parameterized type)
Powder 대입된 자료형

제네릭 클래스 사용 예제

// Plastic 클래스 정의 하기
package generics;

public class Plastic {
    public void doPrinting() {
        System.out.println("Plastic 재료로 출력합니다.");
    }
    public String toString() {
        return "재료는 Plastic입니다.";
    }
}

제네릭에서 대입된 자료형을 명시하지 않는 경우 

GenericPrinter <Powder>와 같이 사용할 자료형 (Powder)를 명시해야 함

자료형을 명시하지 않고 사용할 수 있음 이런 경우 자료형을 명시하라는 경고 표시가 나타남

반환 형에 따라 강제 형 반환을 해야 함

GenericPrinter powderPrinter2 = new GenericPrinter(); // 대입된 자료형 <Powder>를 명시하지 않음
powderPrinter2.setMaterial(new Powder());
Powder powder = (Powder)powderPrinter.getMaterial(); // (Powder) 강제 형 변환
System.out.println(powderPrinter);

<T externds 클래스>

T가 사용될 클래스를 제한하기 위해 사용

출처 Do it 자바 프로그래밍

Material에서 상속받지 않은 Water와 같은 클래스는 프린터 재료로 사용할 수 없음

Material에 정의된 메서드를 공유할 수 있음

 

자료형 매개변수가 두 개인 경우

T, V 두 개의 자료형 매개변수 사용

public class Point<T, V> {
    T x;
    V y;
    
    Point(T x, V y) {
        this.x = x;
        this.y = y;
    }
    
    public T getX() {
        return x;
    } // 제네릭 메서드
    
    public V getY() {
        return y;
    } // 제네릭 메서드
}

제네릭 메서드 활용하기

메서드의 매개변수를 자료형 매개변수로 사용하는 경우 자료형 매개 변수가 하나 이상인 경우

제네릭 메서드의 일반 형식

public<자료형 매개변수> 반환형 메서드 이름(자료형 매개변수...){ }

제네릭 메서드 구현하기

사각형의 너비를 구하는 메서드

두 점의 위치가 여러 자료형으로 사용되는 경우

public class GenericMethod {
    public static <T, V> double makeRectangle(Point<T, V> p1, Point<T, V> p2 {
        double left = ((Number)p1.getX()).doubleValue();
        double right = ((Number)p2.getX()).doubleValue();
        double top = ((Number)p1.getY()).doubleValue();
        double bottom = ((Number)p2.getY()).doubleValue();
        
        double width = right - left;
        double height = bottom - top;
        
        return width * height;
    }
}

제네릭 메서드 사용하기

public static void main(String[] args) {
    Point<Integer, Double> p1 = new Point<Integer, Double>(0, 0.0);
    Point<Integer, Double> p2 = new Point<>(10, 10.0);
    
    double rect = GenericMethod.<Integer, Double>makeRectangle(p1, p2);
    System.out.println("두 점으로 만들어진 사각형의 넓이는 " + rect + "입니다.");
    }
}

컬렉션 프레임워크

프로그램 구현에 필요한 자료구조(Data Structure)를 구현해 놓은 라이브러리

java.util 패키지에 구현되어 있음

개발에 소요되는 시간을 절약하면서 최적화된 알고리즘을 사용할 수 있음

여러 인터페이스의 구현 클래스 사용 방법을 이해해야 함

출처 Do it 자바 프로그래밍

Collection 인터페이스

하나의 객체를 관리하기 위해 메서드가 정의된 인터페이스

하위에 List와 Set 인터페이스가 있음

여러 클래스들이 Collection 인터페이스를 구현함

분류 설명
List 인터페이스 순서가 있는 자료 관리, 중복 허용.
이 인터페이스를 구현한 클래스는 ArrayList, Vector, LinkedList, Stack, Queue 등이 있음
Set 인터페이스  순서가 정해져 있지 않음.
중복을 허용하지 않음.
이 인터페이스를 구현한 클래스는 HashSet, TreeSet 등이 있음

Collection 인터페이스에 선언된 주요 메서드

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

List 인터페이스

Collection 하위 인터페이스

객체를 순서에 따라 저장하고 관리하는데 필요한 메서드가 선언된 인터페이스

배열의 기능을 구현하기 위한 인터페이스

ArrayList, Vector, LinkedList 등이 많이 사용됨

 

ArrayList와 Vector

객체 배열을 구현한 클래스

Vector는 자바 2부터 제공된 클래스

멀티 스레드 상태에서 리소스에 대한 동기화가 필요한 경우 Vector를 사용

일반적으로 ArrayList를 더 많이 사용함

ArrayList에 동기화 기능이 추가되어야 하는 경우

Collections.synchronizedList(new ArrayList<String>());

동기화(synchronization): 두 개의 스레드가 동시에 하나의 리소스에 접근할 때 순서를 맞추어서 데이터에 오류가 발생하지 않도록 함

 

LinkedList 클래스

논리적으로 순차적인 자료구조가 구현된 클래스

다음 요소에 대한 참조값을 가지고 있음

Do it 자바 프로그래밍

요소의 추가 / 삭제에 드는 비용이 배열보다 적음

추가하기

Do it 자바 프로그래밍

삭제하기

Do it 자바 프로그래밍

Stack과 Queue

Stack과 Queue의 기능은 구현된 클래스가 있지만 ArrayList나 LinkedList를 활용하여서 사용할 수도 있음

Stack : Last In First Out(LIFO, 후입선출)

맨 마지막에 추가된 요소가 먼저 꺼내지는 자료구조

바둑, 장기 등의 무르기 기능, 최근 자료 추출 등에서 사용

Do it 자바 프로그래밍

Queue : First In First Out(FIFO, 선입선출)

먼저 저장된 자료가 먼저 꺼내지는 선착순, 대기열 구조

Do it 자바 프로그래밍

Iterator 사용하여 순회하기

Collection의 개체를 순회하는 인터페이스

iterator() 메서드 호출

Iterator ir = memberArrayList.iterator();

선언된 메서드

메서드 설명
boolean hashNext() 이후에 요소가 더 있는지를 체크하는 메서드이며, 요소가 있다면 true를 반환합니다.
E next() 다음에 있는 요소를 반환합니다.

Set 인터페이스

Collection 하위의 인터페이스

중복을 허용하지 않음

아이디, 주민번호, 사번 등 유일한 값이나 객체를 관리할 때 사용

List는 순서 기반의 인터페이스지만, Set은 순서가 없음

저장된 순서와 출력 순서는 다를 수 있음

get(i) 메서드가 제공되지 않음

 

TreeSet 클래스

객체의 정렬에 사용되는 클래스

중복을 허용하지 않으면서 오름차순이나 내림차순으로 객체를 정렬함

내부적으로 이진 검색 트리(binary search tree)로 구현되어 있음

이진 검색 트리에 자료가 저장될 때 비교하여 저장할 위치를 정함

객체 비교를 위해 Comparable이나 Comparator 인터페이스를 구현해야 함

 

Comparable 인터페이스와 Comparable 인터페이스

정렬 대상이 되는 클래스가 구현해야 하는 인터페이스

Comparable은 comparaTo() 메서드를 구현

매개 변수와 객체 자신(this)을 비교

Comparator는 compara() 메서드를 구현

두 개의 매개 변수를 비교

TreeSet 생성자에 Comparator가 구현된 객체를 매개변수로 전달

TreeSet<Member> treeSet = new TreeSet<Member>(new Member());

일반적으로 Comparable을 더 많이 사용

이미 Comparable이 구현된 경우 Comparator를 이용하여 다른 정렬 방식을 정의할 수 있음

 

Comparable 인터페이스 구현 예

public class Member implements Comparable<Member> {
    private int memberId;
    private String memberName;
    
    public Member(int memberId, String memberName) {
        this.memberId = memberId;
        this.memberName = memberName;
    }
	...
	@Override
	public int comparaTo(Member member) {
        return (this.memberId - member.memberId);
    }
    // comparaTo() 메서드 재정의. 추가한 회원 아이디와 매개변수로 받은 회원 아이디를 비교함
}

Map 인터페이스

key - value pair의 객체를 관리하는데 필요한 메서드가 정의됨

key는 중복될 수 없음

검색을 위한 자료구조

key를 이용하여 값을 저장하거나 검색, 삭제할 때 사용하면 편리함 

내부적으로 hash 방식으로 구현됨

index = hash(key) //index는 저장 위치

key가 되는 객체는 유일 성함의 여부를 알기 위해 equals()와 hashCode() 메서드를 재정의 함

 

HashMap 클래스

Map 인터페이스를 구현한 클래스 중 가장 일반적으로 사용하는 클래스

HashTable 클래스는 자바 2부터 제공된 클래스로 Vector처럼 동기화를 제공함

여러 메서드를 활용하여 pair 자료를 쉽고 빠르게 관리할 수 있음

 

HashMap 클래스 사용 예

객체 순회하기

Iterator() 메서드는 하나의 Collection 객체만을 반환하는 pair로 이루어진 객체는 각각 순회해야 함

// Iterator를 사용해 전체 회원을 출력하는 메서드

public void showAllMember() {
    Iterator<Integer> ir = hashMap.keySet().iterator();
    while (ir.hashNext()) { // 다음 key가 있으면
       int key = ir.next(); // key 값을 가져와서
       Member member = hashMap.get(key); // key로부터 value 가져오기
       System.out.println(member);
    }
    System.out.println();
}

TreeMap 클래스

key 객체를 정렬하여 key-value를 pair로 관리하는 클래스

key에 사용되는 클래스에 Comparable, Comparator 인터페이스를 구현

java에 많은 클래스들은 이미 Comparable이 구현되어 있음

구현된 클래스를 key로 사용하는 경우는 구현할 필요 없음

public final class Integer extends Number implements Comparable<integer> {
...
    public int compareTo(Integer anotherInteger) {
        return compare(this.value, anotherInteger.value);
    }

TreeMap 클래스 사용 예

TreeSet 클래스와 같이 필요한 경우 Comparable 혹은 Comparator를 구현함

...
@Override
public int compareTo(Member member) {
    return (this.memberId - member.memberId);
}
// compareTo() 메서드 재정의. 추가한 회원 아이디와 매개변수로 받은 회원 아이디를 비교함

 

728x90
반응형