I. 컬렉션 프레임워크
- 자바에서 자료구조를 구현하여 제공하는 클래스들의 모음
1. List<E>
1-1. 특징
- 배열의 형태이지만, 자동으로 저장공간이 확장된다.
- 인덱스 O -> 저장순서가 지정됨
- 데이터 중복 가능함.
- ArrayList - 배열구조, 멀티쓰레드 X, 데이터탐색 & 순차적인 작업에 빠르다
- Vector - 배열구조, 멀티쓰레드 O
- LinkedList - 체인처럼 인접 참조를 링크한다. 중간 데이터의 추가/삭제는 빠르지만 순차적 작업은 느리다.
1-2. 메서드
- add( index , object ) - 해당 인덱스에 object를 삽입함.
- Object get(int index) - 해당 인덱스의 요소를 리턴해줌
- Object remove(int index) - 해당 index의 데이터를 삭제하고 제거되는 요소를 리턴함
- boolean remove(Object o) - o에 해당하는 객체를 제거함. -> 제거하고 true를 리턴함.
- set(index, object) - 해당 인덱스의 데이터를 object데이터로 교체하고, 기존의 데이터를 리턴함.
- List subList(from Index , to Index ) - 부분리스트 추출
- indexOf(Object o) - 요소 o의 인덱스를 리턴함 - 앞부터 탐색
- lastIndexOf(Object o) - 요소o의 인덱스를 끝에서부터 검사해 리턴함
- boolean constains(Object o) - 요소 o의 존재여부 리턴
1-3. 배열 전체를 List객체에 전달하기
- 주의) 기본데이터 타입의 배열을 전달하면 X!
- Wrapper클래스형의 배열을 전달해야 한다.
- Arrays.asList() 사용한다. -> 매개변수로 추가할 데이터를 전달한다.
-> add() 와 달리 한번에 많은 데이터를 전달할 수 있다.
//1. List객체에 데이터를 연속적으로 전달하기
List arrayList = Arrays.asList(1,2,3,4,5);
System.out.println(arrayList);//[1, 2, 3, 4, 5, 6]
//2. 기본데이터타입 배열을 전달하면 주소값만 나온다.
int[] iArr = {1,2,3,4,5,6};
List arrList = Arrays.asList(iArr);
System.out.println(arrList); //주소값만 나오게된다.
//3. Wrapper클래스 타입의 배열을 사용해야 한다.
Integer[] intArr = {1,2,3,4,5,6};
List intArrList = Arrays.asList(intArr);
System.out.println(intArrList); //[1, 2, 3, 4, 5, 6]
1-4. List 객체의 모든 요소에 접근하는 방법
1) 향상된 for문 사용
2) 일반 for문 사용 - List객체의 get() 메서드 사용해서 출력
1-5. List객체 내의 데이터를 정렬하기, 섞기
- 정렬 -> Collection클래스의 sort() 호출
- 섞기 -> Collection클래스의 shuffle()
- TreeSet 객체 -> List로 변환 & shuffle()
- HashSet객체 -> List로 변환 & sort()
2. Set<E>
2-1. 특징
- 인덱스 X -> 저장순서가 없이 데이터가 저장된다.
- 데이터가 중복되지 않는다. => 중복되지 않는 난수를 생성하여 저장할 때 사용한다. (Ex. 로또번호)
- HashSet - 정렬 X
- TreeSet - '같은 타입'의 데이터가 저장된 Set객체의 데이터를 정렬한다.
2-2. 객체생성방법
//1. 일반적인 객체생성 방법
HashSet hs = new HashSet();
//2. 업캐스팅을 사용한 객체생성 방법 - 부모인터페이스가 대부분의 메서드를 보유하고 있기 때문.
Set set = new HashSet();
//3. Arrays.asList() 사용하여 한번에 여러 데이터 전달하기
Set setAsList = new HashSet(Arrays.asList(1,3,450,20,6));
System.out.println(setAsList);//[1, 450, 3, 20, 6]
2-3. 메서드
- boolean isEmpty() - 컬렉션 객체가 비어있는지 판별함
- int size() - 컬렉션 객체 내의 데이터 갯수를 리턴함
- String toString() - 컬렉션 객체 내의 모든 요소를 문자열로 리턴함 (오버라이딩)
- boolean add(Object o) - 요소(o) 1개를 컬렉션에 추가한 후 성공여부를 리턴함.
- boolean contains(Object o) - 매개변수가 컬렉션에 있는지 검사함
- boolean remove(Object o) - 매개변수를 컬렉션에서 제거함
- Object[] toArray() - 컬렉션의 모든 요소를 담은 배열을 생성하여 리턴함.
- boolean addAll(Collection c) - 다른 컬렉션에 매개변수로 전달한 컬렉션의 모든 요소를 추가시킴
- void clear() - 컬렉션의 모든 요소를 초기화함
2-4. Set객체 내의 데이터에 접근하는 방법
- 인덱스 사용이 불가능하므로 일반 for문으로는 접근이 불가능하다.
=> 향상된 for문을 사용한다.
for(요소를 꺼내 저장할 변수: 컬렉션 객체){}//-> 일단 Object형으로 저장한 후 나중에 다운캐스팅함.
==> List , Set 객체에 접근시 Iterator 객체를 사용한다.
iterator() - Iterator타입 객체 리턴
hasNext() - 다음 요소 존재여부 판별
next() - 다음 요소에 접근
-> List, Set 둘 다 Collection 인터페이스를 구현했고, 객체의 데이터에 접근하는 방법이 완전히 똑같으므로
별도의 메서드를 정의하여 같은 메서드로 접근할 수 있다.
public class Ex01 {
public static void main(String[] args) {
// 통일된 접근을 가능하게하는 static 메서드 printElements(Collection) 정의해서 불러옴
printElements(set);
printElements(list);
}//<<<<<<<<<<<<<<<<<<<<<<main() 메서드 끝>>>>>>>>>>>>>>>>>>>>>>
// Set, List 객체를 전달받아 내부의 모든 요소를 출력하는 메서드를 정의
public static void printElements(Collection c) {//부모인터페이스로 업캐스팅하여 전달받음
Iterator iter = c.iterator();
while(iter.hasNext()) {
Object o = iter.next();
System.out.println("printElements결과: "+o);
}
}
}
3. Map<K , V>
3-1. 특징
- Key & Value 한쌍의 형태를 갖는다.
- Key - 중복 불가능 == Set 객체 형태로 관리하면 편리하다.
- Value - 중복 가능
- HashMap
- Properties
3-2. 메서드
- put(Object key, object value) - 데이터 추가. 두개 다 전달해야함.
- get(Object key) -> 해당 key의 value를 리턴함 / 존재하지 않는 key를 지정하면 null리턴
- Set keySet() - Map 객체 내의 모든 키를 리턴함.
- Collection values() - Map 객체 내의 모든 값을 리턴
- Set, List 타입의 변수에 할당이 불가능하다.
- 다운캐스팅도 불가능
-? 그럼 이건 왜 되는지?
// Set객체로 관리하면 중복을 제거한 값을 출력할 수 있다. Set values = new HashSet(map.values()); System.out.println("Set객체로 map.values()"+values); //[haha, Hello, World] // List객체로 관리하면 중복값 그대로 출력한다. List vals = new ArrayList(map.values()); System.out.println("List객체로 map.values()"+vals); //[World, Hello, haha, haha]
- Set entrySet() - 키와 값을 한 쌍으로 갖는 Map.Entry객체의 모임
- 키&값 한 쌍이 다른 키&값 한쌍과 중복될 수 있으므로 Set타입으로 관리한다.
Set entrySet = map.entrySet();
- isEmpty()
- size()
- Object remove(Object key) - 해당 key&value 한쌍이 제거되고 해당 key의 value가 리턴된다.
- boolean remove(Object o, Object value) - 전달한 key와 value 모두 일치하는 경우에 제거된다.
- 둘 중 하나라도 일치하지 않으면 false리턴됨. - boolean containsKey(Object key) - 해당 key의 존재 여부 리턴
- boolean containsValue(Object o) - 해당 value의 존재 여부 리턴
- void clear() - 모든 키와 값을 초기화함
3-3. 반복문을 통해 Map객체의 데이터에 접근하는 방법
1) 키를 통해( keySet() ) Iterator 반복자로 접근하기
Map객체의 keySet() 호출하여 모든 키를 꺼내 Set객체에 저장한 후
Set객체에 Iterator로 접근한다.
Set keySet2 = map1.keySet();
Iterator iter = keySet2.iterator();
while(iter.hasNext()) {
String phone = iter.next().toString();
String name = map1.get(phone).toString();
System.out.println("이름: "+name+", 전화번호: "+phone);
}
2) 키&값 한 쌍을 통해( entrySet() ) Iterator 반복자로 접근하기
Set entrySet2 = map1.entrySet();
Iterator entryIterator = entrySet.iterator();
while(entryIterator.hasNext()) {
Map.Entry entry = (Map.Entry)entryIterator.next();
//1개의 엔트리에서 getXXX() 메서드를 호출하여 각각의 키,값 가져옴
System.out.println("이름: "+entry.getValue()+", 전화번호: "+entry.getKey());
}
3) 향상된 for문 사용하기
Set keySet3 = map1.keySet();
for (Object phone : keySet3) {
System.out.println("이름: "+map1.get(phone)+", 전화번호: "+ phone);
}
II. Stack & Queue
1. Stack
# 특징
- 데이터를 아래부터 위쪽으로 쌓는 구조
- 데이터 삽입/삭제가 한쪽방향으로만 일어난다. == First In Last Out, Last In First Out
=> 주로 웹브라우저 뒤로, 앞으로 기능 구현시에 사용한다.
# 메서드
- Object push(Object item) - 데이터 item을 추가하고, 해당 데이터를 리턴한다.
- Object peek() - 스택의 맨 위, 즉 가장 마지막에 추가된 요소를 리턴함.
- Object pop() - 스택의 맨 위, 즉 가장 마지막에 추가된 요소를 리턴하고 제거함
2. Queue
# 특징
- 양방향 모두에서 데이터의 이동이 발생하며, 한쪽에서 데이터 삽입, 다른 한쪽에서 데이터 삭제 발생
== First In First Out, Last In Last Out
- Queue는 인터페이스이다. 구현클래스== LinkedList
=> 주로 최근문서항목(?) 이나 선착순 대기열 등 구현시에 사용한다.
# 메서드
- boolean offer(Object o) - 요소 o를 추가 (추가 결과를 boolean타입으로 리턴함)
- Object peek() - 큐의 맨 끝 요소, 즉 가장 먼저 추가된 요소를 리턴한다.
- Object poll() - 큐의 맨 끝 요소, 즉 가장 먼저 추가된 요소를 리턴하고 제거한다.
III. 제네릭
1. 특징
- 클래스 정의 시 데이터타입을 미리 지정하지 않고 임의의 데이터타입으로 선언한 후,
객체 생성 시점에서 특정 데이터 타입을 지정하여 해당 데이터 타입으로 변환하는 방법이다.
ArrayList <Integer> list = new ArrayList<Integer>();
- 데이터 타입은 반드시 Wrapper클래스만 지정할 수 있다!
- Map 객체 생성시 제네릭 타입은 <Key, Value>형식으로 지정한다.
2. 클래스정의시 제네릭타입 지정하기
- 클래스 정의 시점에서 클래스명 뒤에 <가상의 데이터타입> 명시함
- 주로 <E> 또는 <T>
- 가상의 데이터타입이므로 실제 데이터타입으로 사용할 수는 없다.
- 지정된 가상의 자료형은 클래스 내부에서 실제 데이터타입으로 대체된다.
public class Ex02 {
public static void main(String[] args) {
// Integer 타입으로 지정함
GenericClass<Integer> gc = new GenericClass<Integer>();
gc.setData(100);
// String 타입으로 지정함
GenericClass<String> gc3 = new GenericClass<String>();
gc3.setData("Hello world");
// Person타입으로 지정함
GenericClass<Person> gc4 = new GenericClass<Person>();
gc4.setData(new Person("홍길동", 20));
Person p = gc4.getData();
System.out.println("이름: "+p.getName()+", 나이: "+p.getAge());
}
class GenericClass<T>{
T data;
public T getData() { return data; }
public void setData(T data) { this.data = data; }
}
}
3. 제네릭타입 사용시 주의사항
- static 멤버 내에서는 제네릭타입 사용이 불가하다.
-> 제네릭 타입은 인스턴스 생성시 실제 데이터 타입으로 변환되는 반면,
static 멤버는 인스턴스 생성 이전에 로딩되기 때문이다.
- new 연산자 사용시 제네릭 타입 사용 불가능
T tInstance = new T(); //-> 오류난다
- instanceof 연산자에 제네릭타입 사용 불가능
: 컴파일 시점에서 제네릭 타입의 데이터타입 확인이 불가능하기 때문이다.
Object o = new Object();
if(o instanceof T) {...} //-> instancof에 제네릭타입 데이터타입 사용은 불가능하다.
4. 제네릭타입에 지정될 데이터의 종류를 제한할 수도 있다.
class 클래스명<타입파라미터 extends 클래스타입>{...}
//-> 데이터타입은 Number클래스이거나 Number의 하위클래스만 지정이 가능하게 된다.
5. 상속과 인터페이스 구현시에 제네릭타입 지정도 가능하다.
- 동시에 서브클래스 자신만의 제네릭타입을 지정하는 것도 가능하다.
class Class1<P>{}
interface Interface1<Q>{}
// 부모클래스에 제네릭타입이 지정되어있을 경우, 서브클래스에서 상속받을 때 부모의 타입파라미터를 명시해야함.
class SubClass<P,Q,R> extends Class1<P> implements Interface1<Q>{
P var1; //슈퍼클래스 Class1의 타입 P
Q var2; //슈퍼인터페이스 Interface1의 타입 Q
R var3; //서브클래스 자신의 타입 R
}
'개발자 양성과정 필기노트 > JAVA' 카테고리의 다른 글
자바 I/O - 객체 직렬화, 역직렬화 (0) | 2021.11.14 |
---|---|
자바 I/O - 파일 입/출력하기 (0) | 2021.11.14 |
자바 I/O - 데이터 입/출력 하는 방법 (0) | 2021.11.14 |
멀티쓰레딩 (0) | 2021.11.13 |
사용자 정의 예외 (0) | 2021.11.13 |
댓글