기본 콘텐츠로 건너뛰기

Chapter15 컬렉션 프레임워크

 

컬렉션 프레임워크

Collection            List            순서를 유지하고 저장            ArrayList, Vector, LinkedList
                                             중복 저장 가능
                            Set            순서를 유지하지 않고 저장      HashSet, TreeSet
                                             중복 저장 안 됨
Map                                      키와 값의 쌍으로 저장            HashMap, Hashtable, TreeMap, Properties
                                             키는 중복 저장 안 됨
List 컬렉션 - 객체를 인덱스로 관리(저장 순서를 유지)하고 null도 저장 가능
list.add("홍길동");          //맨끝에 객체 추가
list.add(1, "신용권");       //지정된 인덱스에 객체 삽입
String str = list.get(1);    //인덱스로 객체 찾기
list.remove(0);              //인덱스로 객체 삭제
list.remove("신용권");       //객체 삭제
            
            ArrayList - 배열과 다르게 객체를 저장할 용량이 증가하면 자동으로 증가, 인덱스의 객체를 제거하면 바루 뒤 인덱스부터 마지막 인덱스까지 1씩 당겨지고 객체를 삽입하면 반대로 해닥 인덱스부터 마지막 인덱스까지 1씩 밀림, 빈번한 객체 삭제와 삽입은 LinkedList가 인덱스 검색이나, 맨 마지막에 객체를 추가하는 경우에는 ArrayList가 더 좋음
            고정된 객체 들로 구성된 List를 생성할 때는 Arrays.asList(T...a)가 더 간편
            List<T> list = Arrays.asList(T... a);
            List<String> list1 = Arrays.asList("홍길동", "신용권", "감자바");
            
            Vector - Vector는 동기화된 메소드로 구성되어 있기 때문에 멀티 스레드가 동시에 이 메소드들을 실행할 수 없고, 하나의 스레드가 실행을 완료해야만 다른 스레드를 실행(스레드가 안전)하므로 멀티 스레드 환경에서 안전하게 객체를 추가, 삭제 함
            
            LinkedList - LinkedList는 인접 참조를 링크해서 체인처럼 관리하므로 특정 인덱스의 객체를 제거하면 앞뒤 링크만 변경되고 나머지 링크는 변경되지 않음

Set 컬렉션 - List는 저장 순서를 유지하지만, Set 컬렉션은 저장 순서가 유지되지 않고, 객체를 중복해서 저장할 수 없고, 하나의 null만 저장
            Iterator 인터페이스 - 인덱스를 사용하지 않기에 반복자(Iterator)를 제공함
            Set<String> set = ...;
            Iterator<String> iterator = set.iterator();
            while(iterator.hasNext()){
              String str = iterator.next();
              //삭제
              if(str.equals("홍길동")){
                iterator.remove();
              }
            }           
            HashSet - 객체를 저장하기 전에 해시코드를 만들어서 저장되어 있는 객체들의 해시코드를 비교(equals())후 같지 않을 때 저장

Map 컬렉션 - 키와 값으로 구성된 Entry 객체를 저장, 키는 중복 저장될 수 없지만 값은 중복 저장 가능
map.put("홍길동", 30);            //객체 추가
int score = map.get("홍길동");    //객체 찾기
map.remove("홍길동");             //객체 삭제

저장된 객체를 대상으로 하나씩 얻고 싶을 경우 두가지 방법을 사용
//keySet() 메소드로 모든 키를 Set 컬렉션으로 얻은 다음, 반복자를 통해 키를 하나씩 얻고 get() 메소드를 통한 방법
Set<K> keySet = map.keySet();
Iterator<K> keyIterator = keySet.iterator();
while(keyIterator.hasNext()){
  K key = keyIterator.next();
  V value = map.get(key);
}

//entrySet() 메소드로 모든 Map.Entry를 Set 컬렉션으로 얻은 다음, 반복자를 통해 Map.Entry를 하나씩 얻고 getKey()와 getValue() 메소드를 이용해 키와 값을 얻음
Set<Map.Entry<K, V>> entrySet = map.entrySet();
Iterator<Map.Entry<K, V>> entryIterator = entrySet.iterator();
while(entryIterator.hasNext()) {
  Map.Entry<K, V> entry = entryIterator.next();
  K key = entry.getKey();
  V value = entry.getValue();
}
            HashMap - 키로 사용할 객체는 hashCode()와 equals() 메소드를 재정의해서 동등 객체가 될 조건을 정해야함(hashCode()의 리턴값이 같고, equals() 메소드가 true를 리턴), 키와 값의 타입은 기본 타입(byte, short, int, float, double, boolean, char)을 사용할 수 없고 클래스 및 인터페이스 타입만 가능
            Hashtable - Hashtable도 키로 사용할 객체는 hashCode()와 equals() 메소드를 재정의해서 동등 객체가 될 조건을 정해야함, 차이점은 Hashtable은 동기화된 메소드로 구성되어 있기 떄문에 멀티 스레드가 동시에 이 메소드들을 실행할 수는 없고, 하나의 스레드가 실행을 완료해야만 다른 스레드를 실행(스레드가 안전), 멀티 스레드 환경에서 안전하게 객체를 추가, 삭제할 수 있음
            Properties - Hashtable의 하위 클래스이므로 모든 특징을 그대로 가지고 있음, 키와 값을 String 타입으로 제한한 컬렉션, 한글은 유니코드로 저장됨

검색 기능을 강화시킨 컬렉션 - 이진 트리를 이용해서 계층적 구조를 가지면서 객체를 저장하는 TreeSet과 TreeMap을 제공
            이진 트리 구조 
            TreeSet - 
검색 관련 메소드
정렬과 관련된 메소드
//내림차순 정렬
NavigableSet<E> descendingSet = treeSet.descendingSet();
//오름차순 정렬 descendingSet() 메소드를 두번 호출
NavigableSet<E> ascendingSet = descendingSet.descendingSet();
//내림차순 정렬
NavigableSet<E> descendingSet = treeSet.descendingSet();
//오름차순 정렬 descendingSet() 메소드를 두번 호출
NavigableSet<E> ascendingSet = descendingSet.descendingSet();
범위 검색 메소드
//c <= 검색단어 <= f
NavigableSet<String> rangeSet = treeSet.subSet("c", true, "f", true);

            TreeMap - 키와 값이 저장된 Map.Entry를 저장하고, 부모 키값과 비교해서 키 값이 낮은 것은 왼쪽 자식 노드에, 키 값이 높은 것은 오른쪽 자식 노드에 Map.Entry 객체를 저장
검색 관련 메소드
정렬 관련 메소드
//내림차순 정렬
NavigableSet<E> descendingMap = treeMap.descendingMap();
//오름차순 정렬 descendingMap() 메소드를 두번 호출
NavigableSet<E> ascendingMap = descendingMap.descendingMap();
범위 검색 메소드
//c~f 사이의 단어 검색
NavigableMap<String, Integer> rangeMap = treeMap.subMap("c", true, "f", true);
    
            Comparable과 Comparator - TreeSet의 객체와 TreeMap의 키는 오름차순으로 정렬되는데, 정렬을 위해 java.lang.Comparable을 구현한 객체를 사용하고 Comparable에서는 compareTo() 메소드가 정의되어 있으므로 사용자 정의 클래스에서는 이 메소드를 오버라이딩하여 리턴값을 만들어야 함
                                                       - TreeSet 또는 TreeMap 생성자의 매개값으로 정렬자(Comparator)의 compare() 메소드를 정의하면 Comparable 비구현 객체도 정렬 가능함
//오름차순 정렬
TreeSet<E> treeSet = new TreeSet<E>(new AscendingComparator());
//내림차순 정렬
TreeMap<K, V> treeMap = new TreeMap<K, V>(new DescendingComparator());

LIFO와 FIFO 컬렉션 - 후입선출(Last In First Out), 선입선출(First In First Out) 
            Stack - LIFO 자료구조를 구현한 클래스
            Queue - FIFO 자료구조를 구현한 인터페이스이고 대표적인 클래스는 LinkedList임

동기화된 컬렉션 - 싱글 스레드 환경에서 사용하다가 멀티 스레드 환경으로 전환하기 위해서 synchronizedXXX() 메소드가 있음
List<T> list = Collections.synchronizedList(new ArrayList<T>());
Set<E> set = Collections.synshronizedSet(new HashSet<E>());
Map<K, V> map = Collections.synchronizedMap(new HashMap<K, V>());

병렬 처리를 위한 컬렉션 - java.util.concurrent패키지의 ConcurrentHashMap(부분 잠금)과 ConcurrentLinkedQueue(락-프리: 최소한 하나의 스레드가 안전하게 요소를 저장하거나 얻도록)는 멀티 스레드가 병렬적으로 처리하도록 기능을 제공
Map<K, V> map = new ConturrentHashMap<K, V>();
Queue<E> queue = new ConcurrentLinkedQueue<E>();

댓글

이 블로그의 인기 게시물

mac 맥 맥북 Brew 완전 삭제

맥북에서 Brew 초기화 Brew를 써서 h2를 쓰려고 하는데 brew install h2가 안되서 이리 저리 알아보다가 완전 삭제 후 다시 설치 하니까 되서 그 방법을 남겨놈 1. 터미널에 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall.sh)" 입력후 y랑 뭐 비번.. 2. /usr/local 폴더에서 Homebrew 폴더 삭제 rm -rf Homebrew/ 권한설정으로 잘.....삭제하고 3. 다시 설치 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" 좀 오래걸리니까 기다려야한다는걸 배움... 출처.... https://discourse.brew.sh/t/error-no-formulae-found-in-taps/8331/9

메이븐으로 라이브러리 인식

 간혹 퍼블릭 jar가 아닌 파일이 있는데 그럴때 쓰면 될듯 <dependency> <groupId> SimpleCryptLib </groupId> <artifactId> SimpleCryptLib </artifactId> <version> 1.1.0 </version> <scope> system </scope> <systemPath> ${basedir}/src/main/webapp/WEB-INF/lib/SimpleCryptLib-1.1.0.jar </systemPath> </dependency> version, scope, systemPath는 꼭 작성해야 한다 groupId, artifactId, version은 암거나 해도 되는거 같음 최근(2021.05.04)스프링 부트    < dependency > < groupId > NiceID </ groupId > < artifactId > NiceID </ artifactId > < version > 1.0 </ version > < scope > system </ scope > < systemPath > ${basedir}/src/main/resources/lib/NiceID.jar </ systemPath > </ dependency > 이걸 추가해주는것도 필요할지도..?? < build > < plugins > < plugin > < groupId > org.springframework.boot </ groupId > < artifactId > spring-boot-maven-plugi

ORA-28000 계정이 잠금되었습니다 계정 잠길때

오라클 계정이 잠길때 해제방법 증상 t he account is locked 오류 발생 원인 Oracle 에서 t he account is locked  에러가 나는 원인은 ● 잘못된 패스워드로 설정횟수만큼 접속 시도시 Lock. ●  30일동안(Default) 해당 계정으로 로그인을 하지 않았을 경우 Lock. 등이 있다. 해결방법 command창에서 * 로컬일경우, sqlplus "/as sysdba"  또는  sqlplus /nolog  conn /as sysdba  * 로컬이 아닐 경우, sqlplus /nolog conn sys/password@<sid> 이름/패스워드@sid로 입력 로 접속 후 SELECT username, account_status, lock_date FROM dba_users; 으로 Lock이 된 사용자를 확인한 후 LOCKED<TIMED> 라고 되있으면, 패스워드 설정횟수 입력 오류로, 아래의 Unlock 명령만, EXPIRED & LOCKED 라고 되있으면, 패스워드 기간만료로, Unlock 후 비밀번호를 지정해줘야 한다. ALTER USER 사용자명 ACCOUNT UNLOCK; 로 Lock된 사용자를 Unl ock 시킨다 방금 말했다시피, 다시 Lock된 사용자 확인했는데,  Open되지 않고 EXPIRED되어 있다면, alter user 사용자명 identified by 바꿀패스워드;  로 패스워드를 변경하거나 또는 SQL*PLUS 를 재시작하여 Lock를 해제한 계정(사용자명/패스워드)로 로그인 하면 패스워드 변경 창이 뜬다. 추가로 패스워드 Lock 횟수 확인하는 방법은 SELECT U.USERNAME,P.PROFILE, P.RESOURCE_NAME, P.LIMIT  FROM D