190102 자바 컬렉션 프레임워크

2019-01-02

자바 컬렉션 프레임워크

ArrayList

내부적으로 배열 구조를 이용한다.

(+) 장점

  • 인덱스를 가지고 있어 조회 시 O(1) - 대용량 데이터를 한 번에 가져와서 여러번 참조할 때 최상의 성능을 낸다.
  • 크기 조절이 자유롭다.

(-) 단점

  • 데이터 추가/제거를 배열 복사 방식으로 처리하기 때문에 추가/제거시 오버헤드 큼

    • 특히 데이터를 중간에 삽입할 때 데이터들이 뒤로 밀리면서 오버헤드가 커진다.
ArrayList<Integer> aList=new ArrayList<Integer>();

aList.add(1);// 데이터 추가
aList.add(2);
aList.add(3);

aList.get(1);// 해당 인덱스의 값 출력(2)
aList.remove(1);// 해당 인덱스의 값 삭제(1 3)
aList.size();// 리스트의 크기
aList.add(1,4);// (인덱스,값) 해당 인덱스에 해당 값 삽입
aList.indexOf(2);// 값(2)에 해당하는 인덱스 반환. 없을시 -1
aList.set(0,100);// 해당 인덱스의 값을 해당 값으로 변경

ArrayList<Integer> bList=new ArrayList<Integer>();
bList.add(150);
bList.add(200);
aList.addAll(1, bList);// 다른 리스트의 값을 리스트의 해당 인덱스 위치에 모두 추가

aList.isEmpty();// 리스트가 비어있는지 확인
bList.clear();// 리스트 비우기
bList=aList.subList(1,3);// 일부를 잘라서 sub list 생성
LinkedList

C언어의 연결 리스트처럼 다음 자료에 대한 정보만 가지고 있고, 내부 인덱스는 가지고 있지 않은 컬렉션. 단방향과 양방향 존재. 스택/큐/양방향 큐를 만들 때 사용한다.

(+) 장점

  • 중간에 데이터를 추가/삭제하는 경우 O(1) - 추가/삭제가 빈번한 데이터 처리시 사용한다

(-) 단점

  • 검색 성능이 나쁘다(첫 노드부터 계속 탐색해야 한다.) ArrayList와 장단점이 반대!
Vector

스레드 개수와 상관없이 동기화 처리를 한다.

하지만 싱글스레드 환경에서도 동기화 처리를 하기 때문에 성능이 나쁘므로 ArrayList를 사용하기로 하자.

Stack

후입선출(LIFO). ArrayList로 구현하는 것이 적합하다.

Stack<Integer> s=new Stack<Integer>();

s.push(1);// 순차 보관
s.push(2);
s.push(3);

s.isEmpty();// 스택이 비어있는지 판별
s.pop();// 스택의 값을 꺼내서 반환
Queue

선입선출(FIFO). LinkedList로 구현하는 것이 적합하다.

Queue<Integer> queue = new LinkedList<Integer>();

queue.offer(1);// 순차 보관
queue.offer(2);
queue.offer(3);
queue.offer(4);

queue.peek();// 가장 앞의 값을 단순 참조(값 꺼내기 X)
queue.poll();// 가장 앞의 값을 꺼내서 반환. 큐가 비어있으면 null 반환
queue.isEmpty();// 큐가 비어있는지 판별
queue.remove();// 큐에서 객체 삭제(내부에서 poll메소드 사용함). 큐가 비어있으면 예외 던짐
PriorityQueue

우선 순위 큐. 들어온 순서와 관계 없이 우선순위가 높은 엘리먼트부터 나간다.

우선순위가 한 가지 속성으로만 결정될 필요는 없다. 새로운 속성값을 추가해 Comparable, Comparator를 구현하면 여러 가지 조건으로 우선 순위를 결정 가능하다.

class Student implements Comparable<Student>{
    String name;
    int age;
    
    public Student(String name, int age){
        this.name=name;
        this.age=age;
    }
    @Override
    public int compareTo(Student target){
        return this.age<=target.age ? 1:-1 // 나이가 많은 학생 먼저
    }
    @Override
    public String toString(){
        return "이름: "+name+", 점수: "+age;
    }
}
static PriorityQueue<Student> getPriorityQueueOfStudents(){
    PriorityQueue<Student> priorityQueue=new PriorityQueue<>();
    /* 클래스 생성자에 매개변수로 넣어서 compare()를 구현할 수 있다.(아래는 나이가 어린 학생 먼저)
    PriorityQueue<Student> reversedPriorityQueue= new PriorityQueue<>(priorityQueue.size(), new Comparator<Student>() {
    @Override
    public int compare(Student p1,Student p2){
    	return p1.age>=p2.age ? 1:-1;
    }
    });
    
    혹은 람다식으로 표현할 수 있다
    PriorityQueue<Student> reversedPriorityQueue= new PriorityQueue<>(priorityQueue.size(),(Student p1,Student p2)-> p1.age>=p2.age?1:-1);
    */
    priorityQueue.offer(new Student("김철수",35));
    priorityQueue.offer(new Student("이영희",23));
    priorityQueue.offer(new Student("박길동",29));
    priorityQueue.offer(new Student("최민수",17));
    
    return priorityQueue;
}


Map

key-value 쌍으로 연관지어 저장하는 객체. HashMap, TreeMap, LinkedHashMap 등이 있다.