ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [자바] 컬렉션 프레임웍
    자바 2022. 7. 21. 11:47
    728x90

    컬렉션 프레임웍

    데이터 군을 저장하는 클래스들을 표준화한 설계. ( 컬렉션 - 데이터 그룹, 프레임웍 - 표준화된 프로그래밍 방식 
    인터페이스 특징
    List 순서가 있는 데이터의 집합. 데이터의 중복 허용
      구현 클래스: ArrayList, LinkedList, Stack, Vector
    Set 순서를 유지하지 않는 데이터의 집합, 데이터 중복 허용하지 않음
      구현 클래스 : HashSet, TreeSet
    Map 키-값 쌍으로 이뤄진 데이터의 집합, 순서는 유지되지 않고 키는 중복을 허용하지 않고, 값은 중복허용
      구현 클래스 : HashMap, TreeMap, HashTable, Properties

    Vector, HashTable 말고, ArrayList, HashMap 사용 권장

     

    1. 컬렉션 프레임웍의 핵심 인터페이스

    List 인터페이스

    중복을 허용하며 저장순서가 유지되는 컬렉션을 구현하는데 사용된다.

    List의 상속계층도

    List 인터페이스 중요한 메서드들

    public boolean contains(Object o) { return false; }
    public boolean equals(Object o) { return false; }
    public Object set(int index, Object element) { return null; }
    public void add(int index, Object element) { }
    public int indexOf(Object o) { return -1; }
    public int lastIndexOf(Object o) { return -1; }
    public String toString( ) { return ""; }

     

    remove 메서드 설명

    // logic : 삭제할 객체의 바로 아래에 있는 데이터를 한칸씩 위로 복사해서 덮어쓰는 방식, 
    // 만일 삭제할 객체가 마지막 데이터라면, 복사할 필요없이 단순히 null로 변경해주면 된다
    
    public Object remove(int index) {
        Object oldObj = null;
        
        if(index < 0 || index >= size) 
            throw new IndexOutOfBoundsException("범위를 벗어났다");
        oldObj = data[index];
        
        if( index != size-1 ) {
            System.arraycopy(data, index + 1, data, index, size-index-1 );
            // data[index+1]에서 data[index]로 size-index-1 개 만큼 데이터 복사
        }
        
        data[size-1] = null;
        // 데이터가 한칸씩 이동했으니, 마지막 데이터는 null 처리
        size--;
        // 데이터 size 감소
        
        return oldObj;
    }

     

     

    Set 인터페이스

    중복을 허용하지 않고, 저장순서가 유지되지 않는 컬렉션

    set의 상속계층도

    Map 인터페이스

    키-값을 하나의 쌍으로 묶어서 저장하고, 키는 중복되지 않지만 값은 중복될 수 있다.

    map 상속계층도

    value( ) 함수는 중복을 허용하기에 반환타입이 Collection이고,

     keySet( ) 함수는 중복을 허용하지 않기 때문에, 반환타입이 Set타입이다.

     

    Map.Entry 인터페이스

    Map 인터페이스의 내부 인터페이스이고, map 구현시 map.entry 도 구현해야한다.
    public interface Map {
        public static interface Entry {
            Object getKey( );
            Object getValue( );
            Object setValue(Object value);
            boolean equals(Object o);
            int hashCode( );
        }
    }

     

    2. ArrayList

    ArrayList는 list인터페아스를 구현하였고, Vector를 개선한것이며, Object 배열을 이용해 데이터를 순차적으로 저장한다.

     

    주의!

    ArrayList의 요소를 삭제할때는 인덱스를 감소시키면서 삭제해야한다. 증가하면서 삭제를 할 경우에는 한 요소 삭제할 때마다 빈 공간을 채우기 위해서 나머지 요소들이 자리를 이동하기에 올바른 결과가 나올 수 없다.
    ArrayList를 생성할 때는, 새로운 요소 추가시에 자동적으로 크기가 늘어나지만, 시간이 꽤 걸리므로 실제 저장할 개수보다 약간 여유로운 크기로 만들기
    // 객체 생성
    ArrayList list = new ArrayList();
    
    final int LIMIT = 10;
    String source = "123134235asdav"
    int length = source.length();
    
    //여유로운 크기로 만들기
    List list = new ArrayList(length/LIMIT + 10);

     

    size != capacity

     

    // remove method ( ArrayList )
    
    public Object remove(int index) {
        Object object = null;
        
        if (index < 0 || index >= size ) {
            throw new IndexOutOfBoundsException("범위를 벗어났다");
        }
        oldObj = data[index];
        
        if(index != size - 1 )
            System.arraycopy(data,index+1, data,index, size-index-1);
            // data[index+1] 에서 data[index]로 size-index-1개 만큼 데이터 복시한다
        
        
        // 데이터가 모두 한칸씩 이동 했으므로, 마지막 데이터는 null해주기
        data[size-1] = null;
        
        // 데이터가 삭제되었으니 개수 줄이기
        size--;
        
        return oldObj;
    }

    삭제할 객체의 바로 아래에 있는 데이터를 한칸씩 위로 복사해서 삭제할 데이터를 덮어쓰는 방식

    만일 삭제할 객체가 마지막 데이터라면, 복사할 필요없이 단순히 null로 변경해주면 된다.

     

     

     

    2. LinkedList

    배열의 단점은 고정적인 크기, 비순차적인 데이터의 추가 및 삭제에 시간이 올래 걸린다는 점인데, 그 점을 보완하기 위해 생겼으며, 배열과 다르게 불연속적으로 존재하는 데이터를 서로 연결한(link) 형태로 구성되어 있다.
    노드 = 데이터 + 다음요소에 대한 참조(주소값)

    따라서, 중간요소의 삭제는 단 하나의 참조만 변경하면 삭제가 이뤄진다.

     

    더블 링크드 리스트 ( 이중 연결리스트 ) -> 기본적인 linkedList보다 많이 쓴다.

    LinkedList는 단방향으로 다음 요소에 대한 접근은 쉽지만 이전 요소는 어렵다. 

    더블 링크드 리스트는 이전요소에 대한 참조변수를 추가한것이다. 

     

    더블 써큘러 링크드 리스트 ( 이중 원형 연결리스트 )

    더블 링크드 리스트의 첫 번째 요소와 마지막 요소를 서로 연결 시킨 것이다.

     

    ArrayList VS LinkedList ( 성능 차이 )

    1. 순차적으로 데이터 추가 / 삭제시, ArrayList > LinkedList
    2. 중간 데이터 추가 / 삭제시, ArrayList < LinkedList

     

    linkedList가 만일 인덱스가 n인 요소를 얻고자 한다.

    인덱스가 n인 데이터 주소 = 배열의 주소 + n * 데이터 타입의 크기

    이런식으로 처음부터 n까지 차례대로 따라가야 하므로 접근시간이 오래걸린다.

     

    데이터 개수가 변하지 않는다 -> ArrayList
    데이터 개수의 변격이 잦다 -> LinkedList

    처음에 작업하기전 저장은 ArrayList, 작업시에는 LinkedList로 데이터를 옮겨와서 작업하기

     

    3. Stack ,  Queue

    Stack

    선입 후출, ArrayList 같은 배열 기반의 컬렉션 클래스가 적합
    메서드 설명
    boolean empty( ) stack이 비워있는지 확인
    Object peek( ) stack의 맨위 반환, pop과 달리  stack에서 꺼내지는 않음 ( 비워있으면 EmptyStackException 발생)
    Object pop( ) stack맨위 객체 꺼냄( 비워있으면 EmptyStackException 발생)
    Object push(Object item) stack에 객체(item) 저장
    int search(Object o) stack에 주어진 객체 o를 찾아서 위치 반환, 못찾으면 -1반환

     

    사용예시

     

    // 괄호가 올바른지 체크하는 예제
    import java.util.*;
    
    public class ExpValidCheck {
        public static void main(String[] args) {
            if(args.length != 1) {
                System.out.println("Example: \"((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("불일치");
            }
        }
    }

     

    Queue

    선입 선출, ArrayList 같은 배열 기반의 컬렉션 클래스보다는 LinkedList가 적절
    메서드 설명
    boolean add(Object o) 객체를 queue에 추가, 성공시 true 저장공간 부족하면 IllegalStateException 발생
    Object remove( ) queue에 객체 꺼내 반환, 비워있으면 NoSuchElementException
    Object element( ) 삭제 없이 요소 읽기, 비어있으면 NoSuchElementException
    boolean offer(Object o) queue 객체 저장
    Object poll( ) queue에서 객체 꺼내서 반환, 비어있으면 null 반환
    Object peek( ) 삭제없이 요소 읽기, queue비어 있으면 null 반환

     

    history명령어를 queue를 이용해 구현한 예시코드

    import java.util.*;
    
    class Queue {
        static Queue q = new LinkedList();
        static final int MAX_SIZE = 5;
        
        public static void main(String[] args) {
            System.out.println("help 입력시 도움말 보기 가능");
            
            while(true) {
                System.out.prinln(">>");
                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")) {
                        System.out.println(" helq - 도움말 " );
                        System.out.println(" q 또는 Q - 종료 " );
                        System.out.println(" history - 최근 명령어를 " + MAX_SIZE + " 개 보여줌 " ); 
                    } else if (input.equalsIgnoreCase("history")) {
                        int i = 0; 
                        save(input); // 명령어 저장
                        
                        LinkedList tmp = (LinkedList)q;
                        ListIterator it = tmp.listIterator();
                        
                        while(it.hasNext())
                            System.out.println(++i+"."+it.next());
                    } else {
                        save(input);
                        System.out.println(input);
                    }
                } catch(Exception e) {
                    System.out.println("입력오류");
                }
            }
        }
    
        public static void save(String input) {
             // queue 에 저장
             if(!"".equals(input))
                 q.offer(input);
                 
             if(q.size() > MAX_SIZE)
                 q.remove();
         }
    }

     

     

    PriorityQueue

    저장 순서 상관없이 우선순위가 높은것부터 꺼냄 ( null은 저장 못하고 null 저장시 NullPointerException 에러 )

    - 우선순위는 숫자가 작을수록 높다

     

    Deque

    양쪽 끝에 삭제/ 추가가 가능하고, ArrayDeque, LinkedList 같은 구현체가 있다

    deque

    덱 = 스택 + 큐

    스택
    offerLast( ) offer( ) push( )
    pollLast( ) - pop( )
    pollFirst( ) poll( ) -
    peekFirst( ) peek( ) -
    peekLast( ) - peek( )

     

    4. Iterator, ListIterator

    Iterator : 컬렉션에 저장된 요소들을 읽어오는 방법을 표준화 한것이다.

    Iterator( )은 Collection 인터페이스에 정의된 메서드이므로, List과 set에도 포함되어야 하다.

     

    메서드 설명
    boolean hasNext() 읽어 올 요소가 남아있는지 확인한다. 있으면 true, 없으면 false
    Object next( ) 다음 요소를 읽어 온다. next( )를 호출하기 전에 hasNext( )를 호출하는것이 안전하다
    void remove( ) next( )로 읽어 온 요소를 삭제한다. next( )호출 뒤에 remove( )호출 ( 선택적 기능 )

     

    코드

    Collection c = new ArrayList(); // 다른 컬렉션으로 변경시 이 부분만 고치면 된다
    Iterator it = c.iterator();
    
    while(it.hasNExt()) {
        System.out.println(it.next());
    }

     

    Map 인터페이스를 구현한 컬렉션 클래스

    키, 값을 쌍으로 저장하고 있기 때문에 iterator()를 직접 호출할 수 없고, keySet()이나 entrySet()과 같은 메서드로 키,값을 각 따로 set형태로 얻고 iterator()를 호출해야 Iterator를 얻을 수 있다.
    Map map = new HashMap();
    ...
    Iterator it = map.entrySet().iterator();
    // Set eSet = map.entrySet();
    // Iterator it = eSet.iterator();

     

    ListIterator

    Iterator을 상속받아서 기능을 추가한것, 양방향이동이 가능하며, List 인터페이스를 구현한 컬렉션에서만 사용

    Iterator의 메서드에서 양방향 이동이 가능하므로 hasPrevious( ) ( <-> hasNext() ) , previous( ) ( <-> next( ) ) 이런것이 있다.

     

    다만 이동하기 전에 반드시 hasNext( )나 hasPrevious( ) 를 호출헤서 이동할 수 있는지 확인해야한다.

     

    선택적 기능인 add, remove, set 같은 메서드들은 예외를 던져서 구현되지 않는 메서드를 호출하는 쪽에 알리는게 좋다

    public void remove() {
        throw new UnsupportedOperationException();
    }

     

    5. Array

    배열의 복사 - copyOf( ), copyOfRange( )

    copyOf() - 배열 전체를 복사한다
    copyOfRange() - 배열 일부를 복사해서 새로운 배열을 만들어 반환한다. ( 지정된 범위의 끝은 포함하지 않는다. )
    int[] arr = {0,1,2,3,4};
    int[] arr2 = Arrays.copyOfRange(arr,2,4); // [2,3] 4는 불포함
    int[] arr3 = Arrays.copyOf(arr,arr.length); // [0,1,2,3,4]
    int[] arr3 = Arrays.copyOf(arr, 3); // [0,1,2]

     

    배열의 채우기 - fill( ), setAll( )

    fill( ) - 배열의 모든 요소를 지정된 값으로 채운다.
    setAll( ) - 배열을 채우는데 사용할 함수형 인터페이스를 매개변수로 받는다
    int[] arr = new int[5];
    Arrays.fill(arr,9); // arr = [9,9,9,9,9]
    Arrays.setAll(arr, () -> (int)(Math.random() * 5) + 1); // arr = [랜덤숫자 5개]

     

    배열의 정렬과 검색 - sort( ), binarySearch( )

    sort() - 배열을 정렬
    binarySearch( ) - 정렬된 배열을 검색할때 올바른 결과가 나온다 ( 검색속도가 빠르다. )
    int[] arr = { 3,2,0,1,4 };
    
    Arrays.sort(arr); // 정렬 필수
    System.out.println(Arrays.toString(arr)); // [0,1,2,3,4]
    int idx = Arrays.binarySearch(arr,2); // idx = 2

     

    배열 비교,출력 - equals( ), toString( )

    toString( ) - 일차원 배열에서 모든 요소들을 문자열로 출력 ( 다차원은 deepToString( ) 함수 )
    equals( ) -일차원 배열에서 모든 요소 비교 ( 다차원은 deeqEquals( ) 함수 )
    int[] arr = {0,1,2,3,4};
    int[][] arr2 = {{11,12}, {21,22} };
    
    System.out.println(Arrays.toString(arr));
    System.out.println(Arrays.deepToString(arr2));
    
    String[][] arr = new String[][]{{'aa', 'bb'}, {'AA', 'BB'}};
    String[][] arr2 = new String[][]{{'aa', 'bb'}, {'AA', 'BB'}};
    
    System.out.println(Arrays.equals(arr,arr2));
    System.out.println(Arrays.deepEquals(arr,arr2));

     

    배열을 list로 변환 - asList( )

    asList( ) - 배열을 List에 담아서 반환, 반환한 후에는 List의  크기를 변경할 수 없다는 것이다 ( 추가, 삭제 불가능 )

    크기를 변경할 수 있는 List가 필요할때의 코드

    List list = new ArrayList(Arrays.asList(1,2,3,4,5));
    
    // asList 함수 - add, remove() 이런거 안됨
    List list = Arrays.asList(1,2,3,4,5);
    List list = Arrays.asList(new Integer[]{1,2,3,4,5});

     

    5. Comparator와 Comparable

    Comparable - 기본 정렬기준을 구현하는데 사용한다 ( 오름차순 - 사전순 : 대, 소, 숫자 등 모두 구별 )
    Comparator - 기본 정렬기준 외에 다른 기준으로 정렬하고자 할때 사용 ( 내림차순, 다른 기준으로 정렬 )
    import java.util.*;
    
    class ComparatorEx {
        public static void main(String[] args) {
            String[] strArr = { "cat", "Dog", "lion", "tiger" }
            
            Arrays.sort(strArr); // String의 Comparable구현에 의한 정렬
            System.out.println("strArr = " + Arrays.toString(strArr));
            
            Arrays.sort(strArr, String.CASE_INSENSITIVE_ORDER); // 대소 구분x
            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을 곱해서 역순으로 바꿈
                // return c2.compareTo(c1) * -1; 해도 똑같다
            }
            return -1;
        }
    }

     

    6. HashSet

    HashSet - set인터페이스 구현, 중복된 요소 저장하지 않고 저장 순서를 유지 하지 않는다.

    새로운 요소를 추가할때는 add, addAll메서드를 사용하는데 중복된 요소라면 false를 반환한다

    저장순서를 유지하고자 한다면, LinkedHashSet을 사용해야 합니다.

     

    합, 교, 차집합으로 사용할 수 있는 메서드

    생성자 또는 메서드 설명
    boolean addAll(Collection c) : 합집합 주어진 컬렉션에 저장된 모든 객체들을 추가한다
    boolean removeAll(Collection c) : 차집합 주어진 컬렉션에 저장된 모든 객체와 동일한 것들을 HashSet에서 모두 삭제한다
    boolean retainAll(Collection c) : 교집합 주어진 컬렉션에 저장된 객체와 동일한 것만 남기고 삭제한다

     

    HashSet 예시 코드

    Object[] objArr = { "1", new Integer(1), "2", "2" ,"3" };
    Set set = new HashSet(); // 객체 생성
    // Set set = new LinkedHashSet();
    
    for(int i = 0; i < objArr.length; i++) {
        set.add(objArr[i]); // 요소들 저장
    }
    
    // HashSet에 저장된 요소들을 출력한다
    System.out.println(set);
    
    // 1,1,2,3, 이렇게 나오는데 중복된거라고 생각할 수 있다.
    // 하지만 1 한개는 String 인스턴스 나머지는 Integer 인스턴스로 다른 객체여서 중복으로 간주하지 않음

     

    HashSet의 add 메서드 하기 전에 기존에 저장된 것이랑 같은 것이 있는지 체크 해야함 ( by equals(), hashCode() ) 

    -> equals(), hashCode()를 적절히 오버라이딩을 해야한다

    //예시 -> 기존 name과 age & 새로운 name과 age  비교
    public boolean equals(Object obj) {
        if(obj instanceof Person2) {
            Person2 tmp = (Person)obj;
            return name.equals(tmp.name) && age == tmp.age;
        }
        return false;
    }
    
    public int hashCode() {
        retunr Object.hash(name, age);
    }

     

    오버라이딩 된 hashCode가 만족시키는 조건

    1. 실행중인 애플리케이션 내의 동일한 객체에 대해서 여러번 hashCode()를 호출해도 동일한 int 값을 반환해야한다. ( 하지만, 실행시마다 동일한 int 값을 반환할 필요는 없다. )
    2. equals 메서드를 이용한 비교에 의해서 true를 얻은 두 객체에 대해 각각 hashCode()를 호출해서 얻은 결과는 반드시 같아야 한다
    3. equals메서드를 호출했을 때 false를 반환하는 두 객체는 hashCode() 호출에 대해 같은 int값을 반환하는 경우가 있어도 괜찮지만, 해싱을 사용하는 컬렉션의 성능을 향상시키기 위해서는 다른 int 값을 반환하는 것이 좋다
    -> 두 객체에 대해 equals가 true면 해시코드 값은 같아야 하지만, 해시코드 값이 같다고 해서 equalse 결과가 반드시 true는 아니다

     

    7. TreeSet

    - 모든 노드는 최대 2개의 자식노드를 가질 수 있다.
    - 중위 순회 트리 ( L < ROOT < R )
    - 노드의 추가/삭제에 시간이 걸린다 ( 순차적으로 저장하지 않으므로 )
    - 검색(범위검색)과 정렬에 유리하다
    - 중복된 값을 저장하지 못한다

     

    subSet( )을 이용해 범위검색할때 시작범위는 포함되지만, 끝 범위는 불포함 ( 포함하고 싶으면 끝 범위에 'zzz' 추가 )

    TreeSet set = new TreeSet();
    
    String from = "b";
    String to = "d";
    
    set.add("bat");
    // ... 추가
    
    System.out.println(set);
    System.out.println("res 1 : " set.subSet(from, to) );
    System.out.println("res 2 : " set.subSet(from, to + 'zzz') );

     

    hashSet, tailSet

    hashSet - 특정 기준보다 작은 값들 찾아준다
    tailSet - 특정 기준보다 큰 값들 찾아준다
    System.out.println("기준 = 50보다 작은 값 : " + set.haedSet(new Integer(50)));
    System.out.println("기준 = 50보다 큰 값 : " + set.tailSet(new Integer(50)));

     

    8. hashMap

    Map의 특징, 키-값이 하나의 데이터(Entry)로 저장한다는 특징이 있고, 해싱을 하기에 많은 양을 검색하는데 뛰어나다.

    키 - 값은 하나의 클래스로 정의하는 것이 좋다

    // 비객체지향적인 코드
    Object[] key;
    Object[] value;
    
    // 객체지향적인 코드
    Entry[] table;
    class Entry {
        Object key;
        Object value;
    }

     

    Key를 지정할 수 있다 ( by method )

    // 객체 선언 예시
    HashMap map = new HashMap();
    
    // key 지정 메소드
    Object put(Object Key, OBject value); 
    
    // put 예시 코드
    HashMap group = (HashMap)phonebook.get(groupName);
    group.put(tel,name);

     

    기존의 데이터와 중복시에는 새로운 데이터를 만드는 것이 아닌 기존의 데이터에 덮어씌운다

     

    Entry 사용 예시

    import java.util.*;
    
    class HashMapEx {
        public static void main(String[] args) {
            HashMap map = new HashMap();
            
            map.put("아무개", new Integer(100);
            
            Set set = map.entrySet(); // set으로 설정
            Iterator it = set.iterator(); // iterator 객체 설정
    
            while(it.hasNext()) {
                Map.Entry e = (Map.Entry)it.next();
                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()) {
                Integer i = (Integer)it.next();
                total += i.intValue();
            }
            
            System.out.println("총점 : " + total);
            System.out.println("평균 : " + (float)total/set.size());
            System.out.println("최고 점수 : " + Collections.max(values));
            System.out.println("최저 점수 : " + Collections.min(values));
        }
    }

     

    한정되지 않은 범위의 비 순차적인 값들의 빈도수는 HashMap을 통해서 구할 수 있다.

     

    해싱과 해시함수

    해싱 - 해시함수를 이용해 데이터를 해시 테이블에 저장하고 검색하는 기법 ( 자료구조 : 배열 + 링크드 리스트 )

    해싱을 구현한 컬렉션 클래스로는 HashSet, HashMap 등이 있다

    배열과 링크드 리스트의 조합

     

    HashMap에서 저장된 데이터를 찾는 방법

    HashMap에서 저장된 데이터를 찾는 방법

    1. 검색하고자 하는 값의 키로 해시함수를 호출한다.
    2. 해시함수의 계산결과(해시코드)로 해당 값이 저장되어 있는 링크드 리스트를 찾는다.
    3. 링크드 리스트에서 검색한 키와 일치하는 데이터를 찾는다

     

    주의!

    링크드 리스크의 크기가 커지면, 검색속도가 느려진다.

    따라서 하나의 linkedList에는 최소한의 데이터만 저장되게 저장될 데이터의 크기를 고려해서 hashMap의 크기를 지정하고 서로 다른 키에 대해서는 중복된 해시코드 반환을 최소화 해야한다.

     

     

    9. TreeMap

    이진검색트리의 형태로 키와 값의 쌍으로 이뤄져 있어서 검색과 정렬에 적합한 컬렉션 클래스다.
    검색 - hashMap, 범위검색, 정렬 - TreeMap 사용하기

    키에 TreeMap을 사용하면 오름차순으로 정렬된다.

     

    Collections.sort(List list, Comparator c )를 이용해 값에 대한 내림차순으로 정렬한다.

     

    10. Collections

    컬렉션의 동기화

    멀티 쓰레드 프로그래밍에선 하나의 객체를 여러 쓰레드가 동시에 접근할 수 있기 때문에 데이터의 일관성을 유지하기 위해서는 공유되는 객체에 동기화가 필요하다.

     

    필요한 경우에만 java.util.Collections 클래스의 동기화 메서드 사용하기

    // 선언
    static List synchronizedList(List list)
    
    // 사용
    List syncList = Collections.synchronizedList(new ArrayList(...));

     

    변경불가 컬렉션 만들기

    컬렉션에 저장된 데이터를 보호하기 위해서 컬렉션을 변경할 수 없게, 읽기전용으로 만들때 사용한다
    // unmodifiable 을 쓰면 된다
    static List unmodifiableList(List list)

     

    한 종류의 객체만 저장하는 컬레션 만들기

    한 종류의 객체를 저장하고 싶을때 사용한다
    -> 제네릭스를 사용해 간단하게 처리할 수 있다. ( 메서드 제공하는 이유는 호환성을 위함 )
    // checked 사용하기
    static List checkedList(List list, class type);
    
    List list = new ArrayList();
    List checkedList = checkedList(list, String.class); // String만 저장 가능
    checkedList.add("asd");
    checkedList.add(new Integer(3)); // error ClassCaseException

     

    싱글톤 컬렉션 만들기

    단 하나의 객체만 저장하는 컬렉션 ( 변환된 컬렉션은 변경 불가능 )
    //singleton 사용
    static List singletonList(Object o)

     

    11. Collections class 요약

    컬렉션 클래스간의 관계

     

    컬렉션 특징
    ArrayList 배열 기반. 데이터의 추가 삭제에 불리, 순차적인 추가 삭제는 제일 빠름, 임의의 요소에 대한 접근성이 뛰어남
    LinkedList 연결 기반. 데이터의 추가 삭제에 유리. 임의의 요소에 대한 접근성이 나쁨
    HashMap 배열과 연결이 결합된 형태. 추가 삭제 검색 접근성 모두 좋고 검색에 최고임
    TreeMap 연결 기반. 정렬과 검색(특히 범위검색)에 적합. 검색은 hashMap보다 떨어짐
    Stack vector 상속받아 구현
    Queue LinkedList가 Queue인터페이스 구현
    Properties HashTable을 상속 받아 구현
    HashSet HashMap을 이용해 구현
    TreeSet TreeMap을 이용해 구현
    LinkedHashMap
    LinkedHashSet
    HashMap과 HashSet에 저장순서 유지기능 추가

     

     

    '자바' 카테고리의 다른 글

    [자바] 열거형 ( enum )  (0) 2022.07.23
    [자바] 제네릭스  (0) 2022.07.22
    [자바] 날짜와 시간 & 형식화  (0) 2022.07.21
    [자바] 정규형 패턴  (0) 2022.07.15
    [자바] JAVA.LANG패키지와 유용한 클래스  (0) 2022.07.15
Designed by Tistory.