LIFO 자료구조를 구현한 클래스
Stack<E> stack = new Stack<E>();
리턴타입 | 메소드 | 설명 |
---|---|---|
E | puch(E item) | 주어진 객체를 스택에 추가 |
E | peek() | 스택의 최상단(top) 객체를 가져온다. 객체를 제거하지 않음 |
E | pop() | 스택의 최상단(top) 객체를 가져온다. 가져온 객체를 제거함 |
FIFO 자료구조를 구현한 클래스
Queue<E> queue = new Queue<E>();
리턴타입 | 메소드 | 설명 |
---|---|---|
boolean | offer(E e) | 주어진 객체를 추가 |
E | peek() | 가장 처음 추가된 객체(front)를 가져온다. 객체를 제거하지 않음 |
E | pop() | 가장 처음 추가된 객체(front)를 가져온다. 가져온 객체를 제거 |
대부분의 컬렉션 클래스들은 싱글 스레드 환경에서 사용할 수 있도록 설계
멀티 스레드 환경에서 무결성을 보장하지 못함
Vector와 Hashtable은 동기화된 메소드로 구성되어 있어 멀티 스레드 환경에서 안전하게 사용 가능
싱글 스레드 환경에 맞게 설계된 컬렉션 객체들을 동기화된 메소드로 래핑할 수 있도록 Collections가 메소드들을 제공
리턴타입 | 메소드 | 설명 |
---|---|---|
List<> | synchronizedList(List list) | List를 동기화된 List로 리턴 |
Map<K, V> | synchronizedMap(Map<K, V> m) | Map을 동기화된 Map으로 리턴 |
Set | synchronizedSet(Set s) | Set을 동기화된 Set으로 리턴 |
List<T> syncList = Collections.synchronizedList(list);
Map<K, V> syncMap = Collections.synchronizedMap(map);
Set<T> syncSet = Collections.synchronizedSet(set);
다양한 타입의 객체들을 다루는 메소드나 클래스 타입을 미리 명시해 줌으로써 컴파일 시 타입을 체크할 수 있도록 하고, 형변환을 하는 번거로움 없이 사용하게 해주는 것으로 배열이나 이후 배울 컬렉션 사용 시 데이터 타입의 안정성을 높일 수 있다.
제네릭은 클래스와 메소드에 선언 가능
[접근제한자] class [클래스이름]<Type1, Type2, ... > { }
클래스를 선언할 때 클래스 이름 옆에 <>를 이용하여 데이터 타입이나 타입 변수를 지정해주면 된다. 제네릭 타입 변수는 식별자 명명 규칙에 따라 어느 것이든 가능하지만 일반적으로 T를 많이 사용한다. 이후 클래스 내부에 변수나 메소드를 선언할 때 일반 데이터 타입과 동일하게 사용하면 되며, 타입 변수를 특정 데이터 타입으로 지정해주면 해당 타입으로 메모리에 할당하여 사용 가능하다.
public class GenericEx<T> T object; void setObject(T object) { this.object = object; } T getObject() { return object; } } GenericEx<String> ex = new GenericEx<String>();
만약 두 개 이상의 타입으로 제네릭 타입 변수를 사용하고 싶다면 콤마로 구분하여 다른 타입으로 타입 변수를 지정해주면 된다.
메소드에서 사용할 타입을 제네릭을 이용하여 선언할 수 있다.
[접근제한자]<Type1, Type2, ... > [리턴타입] [메소드이름] (매개변수, ...)
제네릭 메소드를 호출할 때에는 타입 변수를 명시적으로 지정할 수도 있고 컴파일러가 매개값의 타입을 보고 추정하도록 할 수도 있다.
일반적인 방법으로 제네릭을 이용했을 경우 타입에 대한 제한이 없다. 하지만 제네릭 타입 변수에 extends 키워드를 사용하면 타입의 종류를 제한할 수 있다.
class Point int x; int y; } class Triangle<T extends Point> { T pos1, pos2, pos3; }
extends 뒤에 명시된 타입의 자손들만 타입 변수에 대입할 수 있게 된다.
타입 변수를 매개변수나 리턴 타입으로 사용할 때 구체적인 타입 대신 와일드 카드를 사용할 수 있다. 타입 변수를 대치할 수 있는 구체적인 타입으로 제한을 두지 않거나 extends 키워드를 이용해 해당 타입과 자손 타입들만 가능하도록 제한하거나 super 키워드를 이용해 해당 타입과 부모 타입들만 가능하도록 제한하는 방법이 있다.
<?> : 제한 없음
<? extends 상위타입> : 상위 클래스 제한
<? super 하위타입> : 하위 클래스 제한
제네릭 클래스도 다른 클래스와 마찬가지로 부모 클래스가 될 수 있다.
부모 클래스의 제네릭 타입을 상속해서 자식 클래스에서도 제네릭 타입을 상속할 수 있다.public class ChildProduct<T, K> extends Product<T, K> { ... }
자식 제네릭 클래스는 추가적인 타입 변수를 가질 수 있다.
public class ChildProduct<T, K, S> extends Product<T, K> { ... }