컬렉션 프레임웍(collections framework)
컬렉션(collection) :여러 객체(데이터)를 모아놓은 것을 의미 +프레임웍 (framework) : 표준화, 정형화 된 체계적인 프로그래밍 방식
- 컬렉션(다수의 객체)을 다루기 위한 표준화된 프로그래밍 방식
- 컬렉션을 쉽고 편리하게 다룰 수 있는 다양한 클래스를 제공
- java.util 패키지에 포함. JDK 1.2부터 제공
컬렉션 클래스(collection class) : 다수의 데이터를 저장할 수 있는 클래스 (Vetctor, ArrayList,HashSet)
컬렉션 프레임웍의 핵심 인터페이스
1. List : 순서 O/ 중복 O ArrayList, LinkedList, Stack, Vector
2. Set : 순서 X/ 중복 X HastSet, TreeSet등
3. Map : 순서 X / 키중복 X/ 값 중복 O HashMap, TreeMap, Hashtable, Properties 등
+ Collection : List와 Set의 공통부분을 뽑은것 (List인터페이스와 Set 인터페이스의 조상)
Collection 인터페이스의 메서드
- 추가 : 지정된 객체 또는 Collection의 객체들을 Collection에 추가함
boolean add (Object o)
boolean addAll(Collection c) - 삭제
boolean remove(Object o) : 지정된 객체 삭제
boolean removeAll(Collection c) : 지정된 Collection에 포함된 객체들 반환
boolean retainAll(Collection c) : 지정된 Collection에 포함된 객체만을 남기고 다른 객체들을 Collection에서 삭제
void clear() : Collection의 모든 객체 삭제 - 검색 : 지정된 객체 또는 Collection의 객체들이 Collection에 포함되어있는지 확인
boolean contains(Object o)
boolean containsAll(Collection c) - 그외
boolean equals(Object o) : 동일한 Collection인지 비교
int hashCode() : Collection의 hash code 반환
boolean isEmpty() : Collection이 비어있는지 확인
Iterator iterator() : Collection의 Iterator를 얻어서 반환
int size() : Collection에 저장된 객체의 개수 반환
Object[] toArray() : Collection에 저장된 객체를 객체배열로 반환
Object[] toArray(Objcet[] a) : 지정된 배열에 Collection의 객체를 저장해서 반환
List인터페이스
- 추가 : 지정된 위치에 객체또는 컬렉션에 포함된 객체들을 추가
void add (int index,Object element)
boolean addAll(int index, Collection c) - 삭제
Object remove(int index) : 지정된 위치에 있는 객체를 삭제하고 삭제된 객체를 반환 - 검색
int indexOf(Object o) : 지정된 객체의 위치를 반환(순뱡향)
int lastIndexOf(Object o) : 지정된 객체의 위치를 반환 (역뱡향) - 그외
Object get(int index) : 지정된 위치에 있는 객체를 반환
Object set(int index, Object element) : 지정된 위치에 객체를 저장
void sort(Comparator c) : 지정된 비교자로 List 정렬
List subList(int fromIndex, int toIndex) : 지정된 범위에 있는 객체 반환
ListIterator listIterator() : List의 객체에 접근 할 수 있는 ListIterator를 반환
ListIterator listIterator(int index) : List의 객체에 접근 할 수 있는 ListIterator를 반환
Set인터페이스
Set인터페이스의 메서드 = Collection인터페이스와 동일
집합과 관련된 메서드가 있음(addAll- 합, containAll - 부분, removeAll- 차, retainAll-교) / boolean타입으로 Colloection에 변화가 있으면 ture, 없이면 false를 반환
Map인터페이스
Hashtable(동기화 o), HashMap**(동기화x), LinkedHashMap(순서o), SortedMap, TreeMap**
- 추가
Object put(Object key, Object value) : Map에 value객체를 key객체에 연결하여 저장
void putAll(Map t) - 삭제
Object remove(Object key) : 지정한 key객체와 일치하는 key-value객체를 삭제
void clear() : Map의 모든 객체 삭제 - 검색
boolean containsKey(Object key) : 지정된 key객체와 일치하는 Map의 key객체가 있는지 확인
boolean containsValue(Object value) : 지정된 value객체와 일치하는 Map의 객체가 있는지 확인 - 읽기
Set entrySet() : Map에 저장되어있는 key-value쌍을 Map.Entry타입의 객체로 저장한 Set으로 반환
Set keySet() : Map에 저장된 모든 key 객체를 반환
Collection values() : Map에 저장된 모든 value객체를 반환 - 그외
int size() : Map에 저장된 key-value쌍의 개수를 반환
boolean equals(Object o) : 동일한 Map인지 비교
Object get(Object key) : 지정한 key객체에 대응하는 value객체를 찾아서 반환
int hashCode() : 해시코드를 반
booleanisEmpty() : Map이 비어있는지 확인
ArrayList
기존의 Vector를 개선한것으로 구현원리와 기능적으로 동일
ArrayList와 달리 Vector는 자체적으로 동기화 처리됨
List 인터페이스를 구현하므로 저장순서가 유지되고 중복 허용
데이터의 저장공간을 배열로 사용(배열기반)
ArrayList의 메서드
- 생성자
ArrayList()
ArrayList(Collection c) : c에 저장된 것을 저장하는 ArrayList를 반환(collection끼리 변환할 떄 사용)
ArrayList(int initialCapacity) : 배열의 길이를 넣어줌 / 배열의 길이를 적절히 저장하는게 중요
-추가하는 메서드
boolean add(Object o) : 성공시 true, 실패시 false반환
void add(int index, Object element) : index는 저장위치
boolean addAll(Collection c) : c요소를 그대로 저장
boolean addAll(int index, Collection c)
-삭제
boolean remove(Object o) : 성공시 true, 실패시 false반환
void add(int index)
boolean removeAll(Collection c) : c에 있는 모든 객체 삭제
void clear() : 모든 객체 삭제
-검색
int indexOf(Object o) : 못찾으면 -1 /순방향
int lastIndexOf(Object o) : 역방향
boolean contains(Object o) : 객체가 존재하는지, 있으면 true
Object get(int index) : 특정 위치의 객체 읽기
Object set(int index, Object element) : 특정 위치에 있는 객체 변경
-
List subList(int fromIndex, int toIndex) : 일부를 뽑아서 서브리스트 만들기
Object[] toArray() : arraylist의 객체배열을 반환
Object[] toArray(Object[] a)
boolean isEmpty() : 비어있는지 확인
void trimToSize() : 빈공간 제거
int size() : arrarylist에 저장된 객체의 개수 반환
import java.util.*;
class Ex11_1 {
public static void main(String[] args) {
ArrayList list1 = new ArrayList(10);
list1.add(new Integer(5));
//list1.add(5)로 써도 됨. autoboxing에 의해(컴파일러가해줌) 기본형이 참조형으로 자동반환(ArrayList에는 객체만 저장가능)
list1.add(new Integer(4));
list1.add(new Integer(2));
list1.add(new Integer(0));
list1.add(new Integer(1));
list1.add(new Integer(3));
//ArrayList(Collection c) 생성자 이용
ArrayList list2 = new ArrayList(list1.subList(1,4));// 1<=x<4 subList는 읽기 전용
print(list1, list2);
//Collection은 인터페이스, Collections는 유틸 클래스(Collection을 다루는데 필요한 메서드 제공)
Collections.sort(list1); // list1과 list2를 정렬한다. 오름차순
Collections.sort(list2); // Collections.sort(List l)
print(list1, list2);
System.out.println("list1.containsAll(list2):" + list1.containsAll(list2)); //리스트1이 리스트2의 모든 요소를 포함하고 있는지 확인
list2.add("B");
list2.add("C");
list2.add(3, "A"); //추가할 위치 지정
print(list1, list2);
list2.set(3, "AA"); //변경
print(list1, list2);
// list1에서 list2와 겹치는 부분만 남기고 나머지는 삭제한다.
System.out.println("list1.retainAll(list2):" + list1.retainAll(list2));
print(list1, list2);
//list.remove(new Interger(1)); 1을 삭제
//list.remove(1); 인덱스가 1인 객체를 삭제
// list2에서 list1에 포함된 객체들을 삭제한다.
for(int i= list2.size()-1; i >= 0; i--) {
if(list1.contains(list2.get(i)))
list2.remove(i);
}
print(list1, list2);
} // main의 끝
static void print(ArrayList list1, ArrayList list2) {
System.out.println("list1:"+list1);
System.out.println("list2:"+list2);
System.out.println();
}
} // class
ArrayList에 저장된 객체의 삭제과정
LinkedList
배열의 장단점
장점 : 구조 간단/ 데이터를 읽는데 걸리는시간(접근시간)이 짧음 (연속적 -> n번째 주소 접근이 쉬움)
단점 : 크기를 변경할 수 없음 (새로운 배열 생성 후 기존 데이터 복사, 참조변경해야함)
비순차적인 데이터의 추가, 삭제에 시간이 많이 걸림(데이터의 추가나 삭제를 위해 다른 데이터를 옮겨야함) (순차적인 데이터는 빠름)
배열의 단점을 보완
- 배열과 달리 불연속적으로 존재하는 데이터를 연결
- 데이터의 삭제 : 단 한번의 참조변경만으로 가능
- 데이터의 추가 : 한번의 node객체 생성과 두번의 참조변수변경만으로 가능
- 이중 연결 리스트(doubly linked list) : 연결리스트는 데이터의 접근성이 나빠서(불연속적) 접근성을 향상시킨게 이중연결 리스트 --> 실제 자바 구현
- 이중 원형 연결 리스트 (doubly circular linked list) : 참조변수를 하나 더 둬서 앞뒤로 이동 가능 (여전히 배열에 비해서는 접근성 낮음)
ArrayList 와 LinkedList 성능비교
-순차적으로 데이터를 추가/삭제 : ArrayList 가 빠름
-비순차적 데이터 추가/삭제 : LinkedList가 빠름
-접근시간 : ArrayList가 빠름
접근시간은 ArrayList가 빠르고 추가 / 삭제는 LinkedList가 빠름(비순차적일 경우)
ArrayList는 비효율적인 메모리사용/ LinkedList는 데이터가 많은수록 접근성이 떨어짐
Stack
LIFO (push/pop) -> 배열 구현이 적합
Stack st = new Stack(); // stack 클래스가 있어 이와 같이 사용가능
-메서드
boolean empty() : stack 이 비어있는지 확인
Object peek() :stack의 맨 위에 저장된 객체를 반환
Object pop() : Stack의 맨 위에 저장된 객체를 꺼냄
Object push(Object item) : stack에 객체를 저장
int search(Object o): stack에서 주어진 객체를 찾아서 그 위치를 반환. 못찾으면 -1을 반환 (배열과 달리 1부터 시작)
-활용
수식계산, 수식괄호검사, 워드프로세스 undo,redo, 웹브라우저의 뒤로/앞으로
import java.util.*;
public class Ex11_3 {
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Usage:java Ex11_3 \"EXPRESSION\"");
System.out.println("Example:java Ex11_3 \"((2+3)*1)+3\"");
System.exit(0);
}
Stack st = new Stack();
String expression = args[0];
System.out.println("expression:" + expression);
try {
for (int i = 0; i < expression.length(); i++) {
char ch = expression.charAt(i);
if (ch == '(') {
st.push(ch + "");
} else if (ch == ')') {
st.pop();
}
}
if (st.isEmpty()) {
System.out.println("괄호가 일치합니다.");
} else {
System.out.println("괄호가 일치하지 않습니다.");
}
} catch (EmptyStackException e) {
System.out.println("괄호가 일치하지 않습니다.");
} // try
}
}
Queue
FIFO (offer/poll) -> 연결리스트 구현이 적합
Queue q =new Queue(); // 이와 같이 사용 불가능 (인터페이스로 정의되어있어서 객체생성 불가능)
// Queue를 구현한 클래스를 사용
Queue q = new LinkedList();// -> 이렇게 쓰면 LlinkList를 queue를 구현한 다른 class로 바꿔도 괜찮음--> 참조변수의 타입은 좁혀주는게 좋다(조상으로))
queue직접 구현 or queue를 구현한 클래스를 사용
-메서드
boolean add(Object o) : 지정된 객체를 queue에 추가/ 성공하면 true 반환/ 저장공간이 부족하면 illegalStateException발생
Object remove() : Queue에서 객체를 꺼내 반환./ 비어있으면 NoSuchElementException발생 --> try -catch 사용
Object element() : 삭제없이 요소 읽어오기/ peek과 달리 Queue가 비었을때 NoSuchElementException발생
Object poll() : Queue에서 객체를 꺼내서 반환/ 비어있으면 null을 반환 (예외발생 X) --> if(obj==null) 사용
Object offer(Object o) : Queue에 객체를 저장
Object peek() : 삭제없이 요소 읽어오기/ 비어있으면 null반환
-활용
최근사용문서, 인쇄작업대기목록, 버퍼
import java.util.*;
class Ex11_4 {
static Queue q = new LinkedList();
static final int MAX_SIZE = 5; // Queue에 최대 5개까지만 저장되도록 한다.
public static void main(String[] args) {
System.out.println("help를 입력하면 도움말을 볼 수 있습니다.");
while(true) {
System.out.print(">>");
try {
// 화면으로부터 라인단위로 입력받는다.
Scanner s = new Scanner(System.in);
String input = s.nextLine().trim();
if("".equals(input)) continue;
if(input.equalsIgnoreCase("q")) {
System.exit(0);
} else if(input.equalsIgnoreCase("help")) { //equalsIgnoreCase : 대소문자 구분 x
System.out.println(" help - 도움말을 보여줍니다.");
System.out.println(" q 또는 Q - 프로그램을 종료합니다.");
System.out.println(" history - 최근에 입력한 명령어를 "
+ MAX_SIZE +"개 보여줍니다.");
} else if(input.equalsIgnoreCase("history")) {
int i=0;
// 입력받은 명령어를 저장하고,
save(input);
// LinkedList의 내용을 보여준다.
LinkedList tmp = (LinkedList)q; //LinkedList로 형변환
//ListIterator it = tmp.listIterator(); listiterator이용
final int SIZE = list.size();// size는 변하지 않으니 final int로 선언하는게 좋음
for(int i=0;i<SIZE;++i)
System.out.println((i+1)+","+list.get(i));
//while(it.hasNext())
//System.out.println(++i+"."+it.next());
} else {
save(input);
System.out.println(input);
} // if(input.equalsIgnoreCase("q")) {
} catch(Exception e) {
System.out.println("입력오류입니다.");
}
} // while(true)
} // main()
public static void save(String input) {
// queue에 저장한다.
if(!"".equals(input)) // if (input!=null && !input.equals("")); 와 동일
q.offer(input);
// queue의 최대크기를 넘으면 제일 처음 입력된 것을 삭제한다.
if(q.size() > MAX_SIZE) // size()는 Collection인터페이스에 정의
q.remove(); //q.poll();과 동일
}
} // end of class
Iterator, ListIterator,Enumeration :
컬렉션에 저장된 데이터를 접근하는데 사용되는 인터페이스
Enumeration은 Iterator의 구버젼
Listerator는 Iterator의 접근성을 향상시킨것 (단방향 -> 양방) (잘 안씀/ 이런게 있다는것만 알면됨)
컬렉션에 저장된 요소들을 읽어오는 방법을 표준화 한것 : 컬렉션들마다 구조가 다달라 요소들을 읽어오는 방법이 다 다른데 이를 표준화 한것 (있는지 확인 -> 읽기)
컬렉션에 iterator()를 호출해서 Iterator를 구현한 객체를 얻어서 사용
List list = new ArrayList() //다른 컬렉션으로 변경할때는 이 부분만 고치면 됨
Iterator it = list.iterator(); //iterator객체를 반환 (일회용)
while(it.hasNext()){ //읽어올 요소 확인
System.out.println(it.next()); //요소를 읽어옴
boolean hasNext() : 읽어올 요소가 남아있는지 확인. 있으면 true 확인
Object next() : 다음요소를 읽어온다
import java.util.*;
class Ex11_5 {
public static void main(String[] args) {
ArrayList list = new ArrayList();
//HashSet list = new HashSet(); 이렇게 할경우 for문 error
//Collection list = new HashSet(); 으로 쓰는게 더 좋음/ 클래스가 바꼈을떄 아래 코드 바꾸지 않아도 됨
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
for(int i=0;i<list.size();++i) {
Object obj = list.get(1); //hashset에서 동작 X
System.out.println(obj);
}
Iterator it = list.iterator(); //hashset에서 동작 - 표준화 되어있음
while(it.hasNext()) {
Object obj = it.next();
System.out.println(obj);
}
} // main
}
iterator는 Collection인터페이스에서 정의되어있어서 Collection의 자손인 List와 set이 모두 가지고 있는 메서드
public interface Collection {
...
public Iterator iterator();
...
}
Map에는 Iterator()가 없다/ Map은 Collection의 자손이 아니기 때문
keySet(), entrySet(0, values() 메서드를 호출해서 set이나 collection를 얻은 다음 iterator를 호출해야함
Map map = new Hashmap();
.
.
.
Iterator it = map.entrySet().iterator();
// Set eSet = map. entrySet();
// Iterator it = eSet.iterator();
Arrays : 배열을 다루기 편리한 메서드(static)제공
1. 배열의 출력 - toString()
2. 배열의 복사 - copyOf(), copyOfRange()
int[] copy_arr = Arrays.copyOF(arr, {length});
int[] copy_arr = Arrays.copyOf(arr,{from},{to}); //이때 fram은 포함, to는 불포함
3. 배열 채우기 - fill(), setAll() - 람다식을 이용해서 채우기
Arrays.fill(arr,9);
Arrays.setAll(arr,(i) -> (int)(Math.random()*5)+1); // 랜덤값(람다식)
4. 정렬과 검색 - sort(), binarySearch() - 이진탐색 -> 정렬후해야함
5. 다차원 배열의 출력 - deepToString()
6. 다차원 배열의 배교 - deepEquals() (1차원 배열의 비교는 equals)
7. 배열을 List로 변환 - asList(Object...a)
List list = Arrays.asList(ne Integer[]{1,2,3,4,5}); //읽기 전용
list.add(6) // UnsupportedOperationException 발생
List list = new ArrayList(Arrays.asList(1,2,3,4,5)); //새로운 list를 만들면 변경가능함
8. 람다와 스트림 관련 - parallelXXX(), spliterator(),stream()
Comparator와 Comparable
- 객체 정렬에 필요한 메서드 (정렬기준 제공)를 정의한 인터페이스
Comparable : 기본 정렬기준을 구현하는데 사용
Comparator : 기본 정렬 기준 외에 다른 기준으로 정렬하고자할때 사용
public interface Comparator{
int compare(Object o1, Object o2); //o1과 o2 두 개체를 비교
boolean equals(Object obj); //equals를 오버라이딩하라는 듯
}
public interface Comparable{
int compareTo(Object o); // 주어진 객체를 자신과 비교
}
- compare()와 compareTo() 는 두 객체의 비교결과를 반환하도록 작성 (같으면 0, 오른쪽이 크면 음수, 작으면 양수)
import java.util.*;
class Ex11_7 {
public static void main(String[] args) {
String[] strArr = {"cat", "Dog", "lion", "tiger"};
Arrays.sort(strArr); // String의 Comparable구현에 의한 정렬 - 객체가 Comparable을 갖고 있을때만 사용가능
System.out.println("strArr=" + Arrays.toString(strArr));
Arrays.sort(strArr, String.CASE_INSENSITIVE_ORDER); // 대소문자 구분안함 //String.CASE_INSENSITIVE_ORDER)는 정렬기준
System.out.println("strArr=" + Arrays.toString(strArr));
Arrays.sort(strArr, new Descending()); // 역순 정렬
System.out.println("strArr=" + Arrays.toString(strArr));
}
}
class Descending implements Comparator {
public int compare(Object o1, Object o2){
if( o1 instanceof Comparable && o2 instanceof Comparable) {
Comparable c1 = (Comparable)o1;
Comparable c2 = (Comparable)o2;
return c1.compareTo(c2) * -1 ; // -1을 곱해서 기본 정렬방식의 역으로 변경한다. (compareTo는 기본정렬기준)
// 또는 c2.compareTo(c1)와 같이 순서를 바꿔도 된다.
}
return -1;
}
}
strArr=[Dog, cat, lion, tiger]
strArr=[cat, Dog, lion, tiger]
strArr=[tiger, lion, cat, Dog]
Integer와 Comparable : Interger는 Comparable를 구현하고 있음
HashSet - 순서X , 중복X
- Set인터페이스를 구현한 대표적인 컬렉션 클래스 - 일반적으로 set이 필요하면 hashset을 사용하면 된다
- 순서를 유지하려면 LinkedHashSet클래스를 사용하면된다
TreeSet
-범위 검색과 정렬에 유리한 컬렉션 클래스
-HashSet보다 데이터 추가, 삭제에 시간이 더 걸림
HashSet 주요메서드
<생성자>
HashSet()
HashSet(Collection c) : 지정된 컬렉션의 모든 객체를 저장
HashSet(int initalCapacity): initalCapacity는 초기용량.
HashSet(int initialCapacity, float loadFactor) : 컬렉션 클래스는 공간을 스스로 느림(보통 2배). 언제 2배로 늘릴건지가 loadFactor.
boolean add(Object o) : 추가
boolean addAll(Collection c) : 합집합
boolean remove(Object o) : 삭제
boolean removeAll(Collection c) : 교집합
boolean retainAll(Collection c) : 조건부 삭제(차집합)
void clear() : 모두 삭제
boolean contains(Object o) : set이 객체를 포함하고 있는지 여부 반환
boolean containsAll(Collection c) : collection에 있는 여러 객체가 모두 포함되어있는지 확인
iterator iterator()
boolean isEmpty() : 비어있는지 확인
int size() : 저장된 객체 수 반환
Object[] toArray() : set에 저장되어있는 객체를 객체 배열로 반환
Object[] toArray(Object[] a)
import java.util.*;
class Ex11_10 {
public static void main(String[] args) {
Set set = new HashSet();
for (int i = 0; set.size() < 6 ; i++) {
int num = (int)(Math.random()*45) + 1;
set.add(new Integer(num));//set.add(num)과 동일
}
List list = new LinkedList(set); // LinkedList(Collection c) //set의 모든 요소를 list에 추가
Collections.sort(list); // Collections.sort(List list) //list 정렬
System.out.println(list);
}
}
set은 정렬불가 / sort의 매개변수는 list만 가능하기 때문! (정렬이라는게 순서를 부여하는것이기때문에,,)
- HashSet은 객체를 저장하기 전에 기존에 같은 객체가 있는지확인 (중복이 허용되지 않기 때문)
- boolean add(Object o)는 저장할 객체의 equals()와 hashCode()를 호출
- equals()와 hashCode()가 오버라이딩 되어있어야함
- hashCode() 메서드:
- hashCode() 메서드는 객체의 해시 코드를 반환합니다. 이 해시 코드는 객체가 해시 테이블 내에서 저장되는 위치를 결정하는 데 사용됩니다.
- 두 객체가 서로 다르더라도 hashCode() 값이 다르다면, 해시 테이블 내에서 서로 다른 위치에 저장될 수 있습니다.
- 따라서 hashCode() 메서드는 객체의 논리적 동등성을 기반으로 일관된 해시 코드를 반환해야 합니다. 즉, 두 객체가 equals() 메서드로 동등하다면, 반드시 같은 해시 코드를 반환해야 합니다.
- equals() 메서드:
- equals() 메서드는 객체의 논리적 동등성을 검사합니다. 두 객체가 논리적으로 같은지를 판단하는 데 사용됩니다.
- HashSet은 equals() 메서드를 사용하여 중복된 요소를 확인합니다. 두 객체가 equals() 메서드로 동등하다면, HashSet은 둘 중 하나만 저장하고 다른 것은 무시합니다.
import java.util.*;
class Ex11_11 {
public static void main(String[] args) {
HashSet set = new HashSet();
set.add("abc");
set.add("abc");
set.add(new Person("David",10));
set.add(new Person("David",10));
System.out.println(set);
}
}
class Person {
String name;
int age;
@Override
public int hashCode() {
//hash메서드의 선언부 : int hash(Object... values); 가변인자 -> 매개변수 마음껏넣어도됨
return Objects.hash(name,age); //iv 넣기
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof Person)) return false;
Person p = (Person)obj; //obj에는 name과 age가 없기 때문에 person으로 형변환
return this.name.equals(p.name)&&this.age==p.age;
}
Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return name +":"+ age;
}
}
import java.util.*;
class Ex11_12 {
public static void main(String args[]) {
HashSet setA = new HashSet();
HashSet setB = new HashSet();
HashSet setHab = new HashSet();
HashSet setKyo = new HashSet();
HashSet setCha = new HashSet();
setA.add("1"); setA.add("2"); setA.add("3");
setA.add("4"); setA.add("5");
System.out.println("A = "+setA);
setB.add("4"); setB.add("5"); setB.add("6");
setB.add("7"); setB.add("8");
System.out.println("B = "+setB);
//교집합
//setA.retainAll(setB); 와 동일
Iterator it = setB.iterator();
while(it.hasNext()) {
Object tmp = it.next();
if(setA.contains(tmp))
setKyo.add(tmp);
}
//차집합
//setA.remove(setB); 와 동일
it = setA.iterator();
while(it.hasNext()) {
Object tmp = it.next();
if(!setB.contains(tmp))
setCha.add(tmp);
}
//합집합
//setA.addAll(setB)와 동일
it = setA.iterator();
while(it.hasNext())
setHab.add(it.next());
it = setB.iterator();
while(it.hasNext())
setHab.add(it.next());
//retainAll로 새로운 합집합 만들기
HashSet tempSet= new HashSet(setA);
//tempSet=setA;
tempSet.retainAll(setB);
System.out.println("SETA = "+ setA);
System.out.println("tempset= "+ tempSet);
System.out.println("A ∩ B = " + setKyo); // 한글 ㄷ을 누르고 한자키
System.out.println("A U B = " + setHab); // 한글 ㄷ을 누르고 한자키
System.out.println("A - B = " + setCha);
}
}
TreeSet - 범위 탐색, 정렬
- 이진 탐색 트리(binary search tree)로 구현. 범위 탐색과 정렬에 유리.
TreeSet의 장점 : HastSet과 달리 따로 정렬을 할 필요가 없음
- 이진 트리는 모든 노드가 최대 2개(0~2개)의 하위 노드를 가짐
각 요소가 나무 형태로 연결 (LinkedList의 변형)
class treeNode{
TreeNode left;
Object element;
TreeNode right;
}
- 이진 탐색 트리 : 부모보다 작은 값은 왼쪽, 큰 값은 오른쪽에 저장
- 데이터가 많아질수록 추가, 삭제에 시간이 더 많이 걸림(비교 횟수 증가)
데이터 저장 : boolean add(Object o) ( hashset은 add 메서드 내에서 equls(), hashcode()등의 메서드를 호출 / TreeSet은 compare()를 호출해서 비교)
주요 생성자와 메서드
<생성자>
TreeSet() : 기본 생성자
TreeSet(Collection c) : 주어진 컬렉션을 저장하는 TreeSet을 생성
TreeSet(Comparator comp) : 주어진 정렬기준으로 정렬하는 TreeSet을 생성 (Comparator 비교 기준/ 없으면 저장하는 객체의 comparable(기본비교기준)을 가지고 비교)
Object first() : 정렬된 순서에서 첫번째 객체를 반환
Object last() : 정렬된 순서에서 마지막 객체를 반환
Object ceiling(Object o ) : 지정된 객체와 같은 객체를 반환. 없으면 큰 값을 가진 객체 중 제일 가까운 값으니 객체를 반환. 없으면 null
Object floor(Object o) : 지정된 객체와 같은 객체를 반환. 없으면 작은 값을 가진 객체 중 제일 가까운 값으니 객체를 반환. 없으면 null
Object higher(Object o) : 지정된 객체보다 큰 객체를 반환. 없으면 null
Object lower(Object o) : 지정된 객체보다 작은 객체를 반환. 없으면 null
TreeSet은 범위검색에 유용한 메서드 제공
SortedSet subSet(Object fromElement, Object toElement) : 범위 검색의 결과를 반환
SortedSet headSet(Object toElement) : 지정된 객체보다 작은 값의 객체들을반환
SortedSet tailSet(Object fromElememt) : 지정된 객체보다 큰 값의 객체들을 반환
TreeSet은 비교기준이 필요하기 때문에 객체가 비교기준을 가지고 있던지 TreeSet이 비교기준을 가지고 있든지 해야함 (Integer는 Comparable을 가지고 있음)
import java.util.*;
// TreeSet이 정렬기준을 가지고 있는경우
class Ex11_13 {
public static void main(String[] args) {
Set set = new TreeSet(new TestComp()); //비교기준을 추가해줘야함
set.add(new Test());
System.out.println(set);
}
}
class Test {
}
class TestComp implements Comparator{
@Override
public int compare(Object o1, Object o2) {
//비교하는 코드
return 0;
}
}
import java.util.*;
//저장하는 객체가 comparable을 가지고 있는 경우
class Ex11_13 {
public static void main(String[] args) {
Set set = new TreeSet();
set.add(new Test());
System.out.println(set);
}
}
class Test implements Comparable {
@Override
public int compareTo(Object o) {
//코드
return 0;
}
}
** 트리 순회(전위, 중위 , 후위)
이진 트리의 모든 노드를 한번씩 읽는 것을 트리순회라고 한다.
중위순회하면 오름차순으로 정렬된
HashMap과 Hashtable - 순서 X, 중복(키X, 값 O)
-Map 인터페이스를 구현. 데이터를 키와 값의 쌍으로 저장
- HashMap(동기화X)은 hashtable(동기화O)의 신버전 -> 동기화는 13장 스레드에서 배움
-HashMap은 HashTable(배열 + 연결리스트)에 데이터를 저장
HashMap
- Map인터페이스를 구현한 대표적인 컬렉션 클래스
- 순서를 유지하려면 LinkedHashMap클래스를 사용하면됨
TreeMap (TreeSet과 같은 특성을 가짐)
- 범위 검색과 정렬에 유리한 컬렉션 클래스
- HashMap보다 데이터 추가, 삭제에 시간이 더 걸림 (비교해야하기 때문)
HashMap의 키와 값
- 해싱(hashing)기법으로 데이터를 저장. 데이터가 많아도 검색이 빠름
- Map인터페이스를 구현 데이터를 키와 값의 쌍으로 저장
해싱(hashing)
- 해시함수를 이용해서 데이터를 저장하고 읽어오는것. 저장할때나 읽어올떄 해시코드(저장위치)가 같아야함!
- 해싱은 해시함수의 성능이 중요한데, Objects.hash()메서드를 사용하면됨.
- 해시 함수로 해시테이블에 데이터를 저장, 검색
- 해시테이블은 배열과 링크드 리스트가 조합된 형태 (배열과 링크드 리스트의 장점을 섞은것)
해시테이블에서 저장된 데이터를 가져오는 과정
1. 키로 해시함수를 호출해서 해시코드(배열의 index)를 얻음
2. 해시코드에 대응하는 링크드리스트를 배열에서 찾음
3. 링크드 리스트에서 키와 일치하는 데이터를 찾음 (해시함수는 같은 키에 대해 항상 같은 해시코드를 반환해야함/ 서로 다른 키일지라도 같은 값의 해시코드를 반환할수도 있음)
주요 메서드
<생성자>
Hashmap()
Hashmap(int initialCapacity) : 배열 초기 용량
Hashmap(int initialCapacity, float loadFactor)
Hashmap(Map m) : 다른 맵을 해쉬맵으로 바꾸는 생성자
* 추가
Object put(Object ket, Object value)
void putAll(Map m)
* 삭제
Object remove(Object key)
* 변경
Object replace(Obejct ket, Object value)
boolean replace(Object ket, Object oldValue, Object newValue)
//해쉬맵에 저장된 데이터를 읽어오는 메서드
Set entrySet() : 키,값(entry)를 set으로 가져오기
Set keySet() : 키 만 가져오기
Collection values() : 값만 가져오기
Object get(Object key) : 특정 key값을 주면 value를 반환
Object getOrDefault(Object ket, Object defaultValue) : key가 없을때 지정된 값 반환
boolean containsKey(Object key) //있으면 true반환
boolean containsValue(Object value) //있으면 true반환
import java.util.*;
class Ex11_17 {
public static void main(String[] args) {
HashMap map = new HashMap();
map.put("김자바", 90);
map.put("김자바", 100); // key중복으로 value값 바뀜
map.put("이자바", 100);
map.put("강자바", 80);
map.put("안자바", 90);
Set set = map.entrySet();
Iterator it = set.iterator();
while(it.hasNext()) {
Map.Entry e = (Map.Entry)it.next(); // Entry인터페이스는 Map인터페이스 안에 내부 인터페이스
System.out.println("이름 : "+ e.getKey() + ", 점수 : " + e.getValue());
}
set = map.keySet();
System.out.println("참가자 명단 : " + set);
Collection values = map.values();
it = values.iterator();
int total = 0;
while(it.hasNext()) {
int i = (int)it.next();
total += i;
}
System.out.println("총점 : " + total);
System.out.println("평균 : " + (float)total/set.size());
System.out.println("최고점수 : " + Collections.max(values)); //max는 comparable을 구현 클래스 객체만 들어올 수 있음
System.out.println("최저점수 : " + Collections.min(values));
}
}
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
//빈도수 계산
class Test0001 {
public static void main(String[] args) {
String[] data = { "A","K","A","K","D","K","A","K","K","K","Z","D" };
HashMap map = new HashMap();
for(int i=0; i < data.length; i++) {
if(map.containsKey(data[i])) { //key 포함여부 확인
int value = (int)map.get(data[i]);
map.put(data[i], value+1); // 있으면 기존값 +1
} else {
map.put(data[i], 1); // 없이면 1저장
}
}
Iterator it = map.entrySet().iterator(); //Map은 collection의 자손이 아님
while(it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
int value = (int)entry.getValue();
System.out.println(entry.getKey() + " : " + printBar('#', value) + " " + value );
}
} // main
public static String printBar(char ch, int value) {
char[] bar = new char[value];
for(int i=0; i < bar.length; i++)
bar[i] = ch;
return new String(bar); // String(char[] chArr)
}
}
Collections - 컬렉션을 위한 메서드(static)를 제공
1. 컬렉션 채우기, 복사, 정렬, 검색 - fill(), copy(), binarySearch등
2. 컬렉션의 동기화 - synchronizedXXX()
static List synList = Collections.sysnchronizedList(new ArrayList(...)); //동기화 되지 않은 list를 넣으면 동기화된 list를 얻을 수 있음. 동기화된 list는 vector클래스를 사용하는 것과 똑같은 결과
3. 변경불가(readOnly)컬렉션만들기 - unmodifiableXXX()
4. 싱글톤 컬레션 만들기 -singletonXXX() : 객체 1개만 저장하는 컬렉션
5. 한 종류의 객체만 저장한는 컬렉션 만들기 : checkedXXX() - 지네릭스 이전 / 지금은 사용할 일 거의 없음.
List list = new ArrayList();
List checkedList = checkedList(list, String.class) //String만 저장가능
checkedList.add("abc");
checkedList.add(new Integer(3)); //error ClassCastException발생
import java.util.*;
import static java.util.Collections.*;
class Ex11_19 {
public static void main(String[] args) {
List list = new ArrayList();
System.out.println(list);
addAll(list, 1,2,3,4,5);
System.out.println(list);
rotate(list, 2); // 반시계방향으로 두번 회전
System.out.println(list);
swap(list, 0, 2); // 첫번째와 세번째를 교환(swap)
System.out.println(list);
shuffle(list); // 저장된 요소의 위치를 임의로 변경
System.out.println(list);
sort(list, reverseOrder()); // 역순정렬 reverse(list)
System.out.println(list);
sort(list); // 정렬
System.out.println(list);
int idx = binarySearch(list, 3); // 3이 저장된 위치(index)瑜� 諛섑솚
System.out.println("index of 3 = " + idx);
System.out.println("max="+max(list));
System.out.println("min="+min(list));
System.out.println("min="+max(list, reverseOrder()));
fill(list, 9); // list를 9로 채운다
System.out.println("list="+list);
// list와 같은 크기의 새로운 list를 생성하고 2로 채운다. 단, 결과는 변경불가
List newList = nCopies(list.size(), 2);
System.out.println("newList="+newList);
System.out.println(disjoint(list, newList)); // 공통요소가 없으면 true
copy(list, newList);
System.out.println("newList="+newList);
System.out.println("list="+list);
replaceAll(list, 2, 1);
System.out.println("list="+list);
Enumeration e = enumeration(list); //iterator와 같은 의미
ArrayList list2 = list(e);
System.out.println("list2="+list2);
}
}
컬렉션 클래스 정리 요약
ArrayList, Vector (Object 배열을 가지고 있고 여기에 객체를 저장 - 배열 기반의 컬렉션 클래스)
이를 이용해서 만든게 Stack
배열의 추가/ 삭제가 불가능하다는 단점을 보완해서 나온게 Linkedlist
이를 이용해서 만든게 queue
array와 linkedlist를 결합해서 나온게 hashmap(key와 value를 쌍으로 저장)
linkedlist 를 활용하여 최대 2개까지 연결가능한게 TreeMap (검색, 범위검색, 정렬기능 향상)
treemap과 HashMap에서 키부분만 가지고 만든게 hashset과 treeset
hashmap(object, object)의 변형으로 Properties(string, string)가 있음 -> 파일에 읽기와 쓰기가 용이
원래 map은 순서가 없지만 순서를 유지하고 싶으면 linked가 붙은걸 사용하면 됨 (linkedhashset, linkedhashmap)
'Study > java' 카테고리의 다른 글
chapter 12 (0) | 2023.08.31 |
---|---|
chapter 9 (0) | 2023.08.12 |
chapter 8 (0) | 2023.08.05 |
chapter 7 -2 (0) | 2023.07.29 |
chapter 7 (0) | 2023.07.22 |