기본 콘텐츠로 건너뛰기

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>();

댓글

이 블로그의 인기 게시물

네이버페이 리뷰 API 연동

네이버 페이 리뷰 API 네이버 측에 문의 하면 sandbox용 인증키를 받습니다. AccessLicense, SecretKey 그리고 받은 파일의 4. WSDL을 열어 주시고 Naver_Pay_API_MallService41_WSDL(sandbox)_20140925파일 압축 풀어주세요 그럼 파일이 BaseType.xsd, CheckoutAPI.wsdl, MallServiceMessage.xsd 세개의 파일이 나옵니다. 네이버페이 리뷰 리스트 가져오는 메소드는 getPurchaseReviewList입니다. BaseType.xsd를 켜신 후 MallID로 검색하면 <xs:complexType name="purchaseReview"> 안쪽의 MallID밑에  <xs:element minOccurs="0" name="PurchaseReviewClassType" type="xs:string"/> 추가해주세요 포토 리뷰를 가져오는 파라미터 값을 보내기 위해서 입니다. <xs:element minOccurs="0" name="Content" type="xs:string"/> 이값도 필요합니다 이미지 경로를 가져오기 위해서 입니다. <xs:complexType name="purchaseReview">     <xs:sequence>       <xs:element minOccurs="0" name="CreateYmdt" type="xs:dateTime"/>       <xs:element minOccurs="0" name="MallID" type="xs:string"/>   <xs:element minOccurs="0" nam...

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

OCI에 서버 세팅하기

    1. 서버 기본 준비      OCI A1 인스턴스를 만들고 Ubuntu 같은 OS를 설치합니다. A1은 ARM 기반이므로, 사용하는      Docker 이미지와 의존성이 linux/arm64를 지원하는지 먼저 확인해야 해요. 특히 일부 오래된      DB 이미지나 네이티브 모듈은 주의가 필요합니다.   2. 네트워크와 보안 설정      OCI 보안 목록/NSG와 서버 방화벽에서 최소한 80, 443, 22 포트를 정리합니다.       - 80: HTTP 및 인증서 발급       - 443: HTTPS       - 22: SSH 관리용 — 가능하면 내 IP만 허용      앱 컨테이너의 포트(예: 3000, 8080, DB 포트)는 인터넷에 직접 열지 않는 게 핵심입니다.   3. Docker 운영 기반 구성      서버에 Docker와 Docker Compose 플러그인을 설치하고, 프로젝트별 디렉터리를 분리합니다.      예를 들면:      /srv/apps/        promeditor/        other-project/        proxy/      각 프로젝트는 자기 compose.yml, 환경변수 파일, DB 볼륨을 독립적으로 가지게 합니다.   4. 공용 Nginx 리버스 프록시 구성      Nginx는 한 개만 앞단에서 실행하고, 도메인/서브도메인에 따라 내부 컨테이너로 프록시합니      다...