본문 바로가기

JAVA/JAVA 기초

자바 컬렉션관련

반응형

배열의 한계

복수의 데이터를 취급하기 위해 배열을 사용했다.

그러나 배열은 길이가 결정되어 있기 때문에 요소의 추가나 삭제가 어려운 문제가 있다.

그래서 자바에서는 복수의 데이터를 좀 더 다루기 쉬운 구조로 '컬렉션'을 준비했다.

컬렉션과 반복자, 그리고 컬렉션을 다루기 위한 유틸리티 등의 집합을 컬렉션 프레임워크라 부른다.


컬렉션은 배열과 달리 처음부터 크기의 제한을 결정할 필요가 없기 원하는 만큼의 데이터를 저장할 수 있다. 

또한 컬렉션 프레임워크는 많은 인터페이스와 구현이 준비되어 있어, 각각 다른 알고리즘으로 데이터를 관리한다.

배열처럼 여러 데이터를 처리할 수 있는 List 인터페이스와 키와 값을 나누어 데이터를 유지하는 Map 인터페이스 등이 있다.


대표적인 컬렉션

배열 - 복수의 요소를 취급하는 매커니즘, 유연성이 떨어진다.

List - 배열처럼 복수의 요소를 취급할 수 있으며, 인덱스를 지정해서 값의 취득이나 설정을 할수 있다.

Set - List와 비슷하지만 중복하는 경우는 등록하지 않기 때문에 중복 없는 복수의 요소를 취급할 수 있다. 순서가 없기 때문에 인덱스를 지정하여 값을 취득, 설정할 수 없다.

Map - 키와 값을 이용하여 요소를 취급할 수 있다. 딕셔너리라고 불리기도 한다. Set과 마찬가지로 순서성이 없다.



List 인터페이스


add - 요소 추가 - 인수로 지정한 요소를 리스트에 추가

addAll  - 모든 컬렉션의 요소 추가 - 인수로 지정한 컬렉션 안에 모든 요소를 리스트에 추가

set - 요소 덮어쓰기 - 인수로 지정한 위치에 있는 요소를 인수로 지정한 요소로 덮어 쓴다.

remove - 요소 제거 - 인수로 지정한 위치에 있는 요소를 리스트로부터 삭제한다.

removeAll - 일치하는 요소의 삭제 - 인수로 지정한 컬렉션에 포함된 요소를 리스트에서 삭제한다.

retainAll - 일치하지 않는 요소의 삭제 - 인수로 지정한 컬렉션에 일치하는 요소만을 리스트에 남기고 나머지 요소를 삭제한다.

clear - 모든 요소의 삭제 - 모든 요소를 리스트에서 삭제한다.


get - 요소의 취득 - 인수로 지정한 위치에 있는 요소를 리스트로부터 취득한다.

size - 요소의 크기 - 리스트 내의 요소의 수를 취득

isEmpty - 비어있는지 판정 - 리스트에 요소가 없는지를 판정

subList - 범위 내의 요소 취득 - 인수로 지정한 시작 위치와 종료 위치의 사이에 있는 요소를 취득한다.

toArray - 배열로 전환 - 리스트 내의 모든 요소를 배열로서 취득한다.


contains - 요소의 검색 - 인수로 지정한 요소가 리스트에 포함되어 있는지 판정한다.

containsAll - 모든 요소의 검색 - 인수로 지정한 컬렉션 안에 모든 요소가 리스트에 포함되어 있는지를 판정한다.

indexOf - 처음에 검색된 요소의 위치를 취득 - 인수로 지정한 요소가 리스트 내에서 처음에 발견된 위치를 취득한다.

lastIndexOf - 마지막에 검색된 요소의 위치를 취득 - 인수로 지정한 요소가 리스트 내에서 마지막에 발견된 위치를 취득한다.


iterator - 반복자의 취득 - 리스트의 반복처리를 적절하게 실시하기 위한 반복자를 취득한다.

listIterator - 리스트 반복자의 취득 - 전방처리나 추가, 변경 처리등을 실시하는 반복자를 취득한다.


ArrayList - 가장 대표적인 List의 구현 클래스. 내부에 배열을 갖고 있어 루프 처리등을 고속으로 할수 있다.

LinkedList - 앞뒤의 참조를 갖고서 순서를 유지하는 클래스, 리스트의 중간에서 요소의 추가, 삭제를 고속으로 할 수 있다.

CopyOnWriteArrayList - ArrayList를 스레드 세이프화한 클래스



package com.eeswk;


import java.util.ArrayList;

import java.util.Arrays;

import java.util.List;


public class ListSample {


public static void main(String[] args) {

List<Integer> list = new ArrayList<>();

list.add(1);

list.add(2);

list.add(10);

list.add(4);

List<Integer> arrayList = new ArrayList<>(Arrays.asList(1, 2, 10, 4));


List<Integer> integerList = Arrays.asList(1, 2, 10, 4);

list.add(5);

arrayList.add(5);

// integerList.add(5); //java.lang.UnsupportedOperationException


System.out.println(list.toString());

System.out.println(arrayList.toString());

System.out.println(integerList.toString());

System.out.println(integerList.indexOf(10));

}


}


값검색

요소를 검색하기 위해서는 indexOf메서드를 사용한다.

일치하는 요소의 인덱스를 취득한다. 그리고 리스트의 선두부터 순서대로 요소를 검색(선형검색)하고 최초로 발견된 요소의 인덱스를 반환한다. 일치하는 요소가 없으면 -1을 반환한다.


contains 메서드는 인덱스를 반환하는 것이 아니라 요소가 있는지 없는지를 반환해준다(true/false)

그러나 일반적으로 선형검색은 처리가 느리기 때문에 요소 수가 많거나 자주 검색해야 하는 경우 검색처리를 실시하는 편이 좋다. 중복요소가 없다면 set인터페이스를 사용하는 편이 더 빠르다.



List<Integer> list = Arrays.asList(1, 2, 10, 4);


asList 메서드를 사용할 경우 List에 대해 요소의 추가, 변경, 삭제를 할 수 없다.

Arrays.asList 메서드로 작성한 클래스는 일반적인 ArrayList와 약간 달라서 읽기 전용의 List 구현이다.


List 정렬

java.util.Collections 클래스의 sort 메서드를 사용한다.



Comparator<Integer> c = new Comparator<Integer>() {

@Override

public int compare(Integer o1, Integer o2) {

return o1.compareTo(o2); //오름차순

return o2.compareTo(o1); //내림차순

}

};

Collections.sort(list, c);

System.out.println(list.toString());


List 검색

Collections 클래스의 binarySearch 메서드를 사용한다.


int found = Collections.binarySearch(list, 5);

System.out.println(found);


List의 반복자

List에 보관되어 있는 요소를 동일한 처리를 하는 경우 for문(for-each)사용


for(int i : list) {

System.out.println(i);

}


Itertor 인터페이스를 사용

다음요소가 있는지를 확인하는 hasNext 메서드

다음 요소를 실제로 취득하는 nex 메서드


for (Iterator iterator = list.iterator(); iterator.hasNext();) {

Integer integer = (Integer) iterator.next();

System.out.println(integer);

}


반복처리를 하면서 컬렉션으로 부터 요소를 삭제할 수 있다.


Iterator<Integer> iterator = list.iterator();

while(iterator.hasNext()) {

Integer i = iterator.next();

if(i == 5) {

iterator.remove();

}

}

for(int i : list) {

System.out.println(i);

}



List 구현클래스


CopyOnWriteArrayList 클래스

복수의 스레드로부터 동시에 액세스해도 올바로 처리되는 ArrayList 클래스의 확장이다.

스레드란 프로그램의 실행의 흐름을 나타내는 단위이다.

처음에 main 메서드가 시작하고 거기에서 다음의 메서드가 호출되면 return으로 되돌아와 그 다음의 메서드가 실행되는 계속되는 이러한 흐름을 스레드라고 한다.

스레드는 여러 개 만들어 각 처리르 변행으로 실시할 수 있다.

ArrayList 클래스에서 특정 스레드에서 iteration이나 for-each문을 사용한 루프를 실행하고 있을 때에 별개의 스레드가 그 ArrayList 객체의 요소를 변경하면 ConCurrentModification Exception이 발생한다.

ArrayList는 여러 스레드로부터 변경 조작을 포함하는 액세스를 할수 없다.


CopyOnWriteArrayList 클래스는 iterator나 for-each문을 사용한 루프를 실시할 때에 원래의 리스트의 복사본을 작성하여 그 복사본에 대해서 루프를 실시한다.

그래서 다른 스레드가 리스트의 조작을 실시해도 루프 쪽의 리스트에 영향을 미치지 않아 예외가 발생하지 않는다.

하나의 리스트 객체에 대해 여러 스레드가 동시에 액세스할 가능성이 있는 경우는 CopyOnWriteArrayList 클래스를 사용한다.

성능면에서는 ArrayList와 거의 ㅂ슷하다.

단 요소를 추가/변경/삭제 할경우 CopyOnWriteArrayList에서는 내부적으로 갖고 있는 배열을 복사하기 때문에 ArrayList에 비해 성능이 나빠진다.


리스트 객체를 일기 전용으로 하는 UnmodifiableList 클래스도 있다.



 클래스

 추가 

 삽입 

 값의 취득 

 검색 

 ArrayList 

 good

 good

 best

 bad

 LinkedList 

 best

 best

 bad

 bad

 CopyOnWriteList 

 good

 good

 best

 bad


배열의 중간에 요소를 추가나 삭제를 실시하는 일이 많다 => LinkedList

for문등을 사용한 전체적인 반복처리가 많다 => ArrayList

복수의 스레드를 동시에 액세스 한다 => CopyOnWriteArrayList



Map 인터페이스

키와 값의 조합으로 값을 취급한다.


put - 요소의 추가 - 인수로 지정한 요소를 Map에 추가

putAll - 모든 Map 요소의 추가 - 인수로 지정한 Map 안의 모든 요소를 Map에 추가한다.

remove - 요소의 삭제 - 인수로 지정한 키를 갖고 있는 요소를 map에서 삭제한다.

clear - 모든 요소의 삭제 - 모든 요소를 Map에서 삭제한다.


get - 요소의 취득 - 인수로 지정한 키를 갖는 요소의 값을 Map에서 취득한다.

size - 요소의 크기 - Map안에 있는 요소의 수를 취득한다.

isEmpty - 비어있는지 판정 - Map에 요소가 없는지 판정한다.

entrySet - 요소 집합을 취득 - Map안에 있는 모든 요소의 집합을 취득한다.

KeySet - 키 집합을 취득 - Map안에 있는 모든 요소의 키의 집합을 취득한다.

values - 키의 컬렉션을 취득 - Map안에 있는 모든 요소의 값의 컬렉션을 취득한다.


containsKey - 키의 검색 - 인수로 지정한 키를 갖는 요소가 Map에 포함되어 있는지 판정

containsValue - 값의 검색 - 인수로 지정한 값을 갖는 요소가 Map에 포함되어 있는지 판정


forEach - 모든 요소의 처리 - Map 내의 모든 요소가 순차적으로 콜백함수에 건네지고, 콜백함수에서 요소에 대한 처리를 한다.


Map<Integer, String> map = new HashMap<>();


map.put(1, "하나");

map.put(2, "둘");

map.put(3, "셋");


클래스의 초기화 시에 Map도 초기화하고 싶은 경우

package com.eeswk;


import java.util.HashMap;

import java.util.Map;


public class MapTest {


private static final Map<Integer, String> map;

static {

map = new HashMap<>();

map.put(1, "하나");

map.put(2, "둘");

map.put(3, "셋");


System.out.println(map.containsKey(1));

System.out.println(map.containsValue("셋"));

map.put(3, "Three");

System.out.println(map.containsValue("셋"));

}

}


containsValue 메서드로 지정한 값이 존재하는지를 체크할 때 일반적으로 내부에서 선형검색을 실시하고 있으므로 요소가 많아질수록 처리가 늦어진다.

가급적 사용하지 않도록 한다.



Map 구현 클래스 

HashMap

키로부터 해시값을 계산하여 내부의 해시 테이블이라는 표에 키와 값을 지정하는 방식으로 요소를 관리한다.

해시 테이블은 값을 저장하는 위치의 인덱스가 키로부터 산출한 해시값을 이용하여 키에 해당하는 값을 빠르게 참조할 수 있는 데이터 구조다.

해시값의 계산은 키의 객체의 hashCode 메서드에 의해 실행된다.

계산의 결과의 값을 해시 테이블의 크기로 나눈 나머지를 값이 저장되는 위치의 인덱스로 사용한다.

키가 달라도 hashCode 메서드의 반환 값이 동일한 값이 될수 있다. 그러한 것을 상정하여 각가의 위치는 LinkedList와 같은 구조로 되어 있다. 이미 값이 보관되어 있는 인덱스에 새로운 값을 보관하는 경우는 List의 끝에 키와 값의 세트를 추가한다.

값을 꺼내느 경우도 해시값을 바탕으로 요소를 식별한다.

해시값으로 계산된 저장 위치에 여러 값이 보관되어 있는 경우는 맨 앞부터 순서대로 equals메서드를 사용하여 키가 일치하는 요소를 검색한다.


해시 테이블의 초기 크기는 16이지만 테이블의 크기에 대해 보관하는 요소의 개수의 비율이 커지면 해시값이 충돌할 가능성이 높아져 값을 저장하는 효율이 떨어진다. 따라서 어느정도 요소가 많아지면 (기본설정에는 해시 테이블 크기의 75%) 해시 테이블의 크기를 확대하는 처리가 수행되어 저장하는 요소가 많아져도 효율이 떨어지지않도록 되어있다.

HashMap에서는 요소의 위치를 해시로 계산하기 때문에 키를 그대로 취급하는 다른 클래스에 비해 빠르게 처리할 수 있다.

단 요소를 추가할때에 해시 테이블의 크기를 확장하는 처리와 요소의 추가 처리가 동시에 진행되는 경우 무한루프에 빠질 수 있다.

따라서 HashMap에 대해 여로 스레드에서 동시에 액세스하는 경우는 조치가 필요하다

- 여러 스레드로부터 동시에 액세스할 수 없도록 synchronized등을 동기화한다.

- 여러 스레드로부터 액세스해도 안전하게 사용할 수 있는 ConcurrentHashMap을 사용한다.


HashMap에서 요소의 추가 순서는 유지되지 못한다.

반복자로 요소에 대해 반복 처리르 실시할때는 일밙거으로 HashMap에 추가된 순서와 다른 순서로 값이 출력된다.



LinkedHashMap

HashMap의 서브클래스이다.

그렇기 때문에 특징은 HashMap과 동일하다.

HashMap과 다른점은 요소 자체가 앞뒤 정보를 갖고 있기 때문에 LinekdHashMap에 요소를 추가한 순서가 유지된다는 점이다.

추가한 순서가 유지되기 때문에 반복자에서 요소에 대해 반복 처리할 때는 LinkedHashMap에 추가한 순서래도 요소가 추출된다.


요소의 추가/삭제에 대해서는 HashMap에 비하여 요소 간 링크의 재설정 필요하므로 LinkedHashMap 쪽이 약간 성능이 떨어지지만 거의 손색이 없다. 키를 지정하는 값의 취득은 HashMap과 동일한 처리이므로 성능차가 없다.

iterator나 for-each문을 사용한 루프튼 요소 간의 링크를 탐색하여 요소를 열거하기 때문에 LinkedList와 거의 같은 성능이 나온다.

루프에서는 해시 테이블 내의 요소를 열거할 때 해시값이 중복되는 요소가 보관되어 있으면 그곳에서 다시 List의 열거가 발생해 성능이 약화된다. 그 때문에 요소의 열거에 대해서는 일반적으로 LinkedHashMap쪽이 고속이다.


TreeMap

키의 값을 베이스로 이진 탐색 트리의 알고리즘에 따라 요소를 정렬하는 클래스다.

이진 탐색 트리의 알고리즘은 요소를 추가할 때에 "왼쪽자손의 값 <= 부모의 값 <= 오른쪽 자손의 값"이라는 조건으로 트리구조를 만들어 요소를 정렬함으로써 값의 탐색을 효율화한다.

정렬은 요소를 추가할 때 실시되고 요소는 TreeMap의 내부에서 정렬된 상태로 보관된다.

TreeMap은 다른 Map에서는 할수 없는"00이상 00이하의 키를 갖는 요소를 취득하기"나 "00보다 큰, 가장 가까운 키를 갖는 요소의 취득"등 크고 작음을 의식한 값의 취득이 가능하다.

한편 요소의 추가/삭제/검색은 내부의 이진 탐색 트리의 구조를 탐색할 필요가 있기 때문에 최악의 계산량으로 O(log n)이 시간이 필요하다.

빈번하게 요소의 추가/삭제/검색을 실시하는 경우는 HashMap등의 Map에 비해 처리 시간의 차가 현저하게 나타난다.


 클래스

 추가 

 취득 

 열거 

 HashMap 

 best

 best

 best

 LinkedHashMap 

 best

 best

 best

 ConcurrentHashMap 

 good

 good

 good

 TreeMap 

 normal

 normal

 normal


키의 대소를 의식한 부분 집합을 취급할 경우 => TreeMap

요소의 순서를 유지할 필요가 있는 경우 => LinkedHashMap

복수 스레드로부터 동시에 액세스 할 경우 => ConcurrentHashMap

그외의 경우 => HashMap


Set 인터페이스

값의 집합을 취급할수있는 인터페이스


add - 요소의 추가 - 인수로 지정한 요소를 set에 추가

setAll - 모든 set 요소의 추가 - 인수로 지정한 컬렉션 안의 모든 요소를 Set에 추가한다

remove - 요소의 삭제 - 인수로 지정한 요소를 set에서 삭제한다.

removeAll - 일치하는 요소의 삭제 - 인수로 지정한 컬렉션에 포함된 요소를 set에서 삭제한다

retainAll - 일치하지 않는 요소의 삭제 - 인수로 지정한 컬렉션과 일치하는 요소만 set에 남기고 다른 요소를 삭제한다.

clear - 모든 요소의 삭제 - 모든 요소를 set에서 삭제한다.


size - 요소의 크기 - set안에 있는 요소의 수를 취득한다.

isEmpty - 비어있는지 판정 - set안에 요소가 없는지 판정한다.

toArray - 배열로의 전호나 - set안에 있는 모든 요소를 배열로 취득한다.


contains - 요소의 검색 - 인수로 지정한 요소가 set에 포함되어 있는지 판정한다.

containsAll - 모든 요소의 검색 - 인수로 지정한 컬렉션 내의 모든 요소가 set에 포함되어 있는지를 판정한다.


iterator - 반복자의 취득 - 반복 처리를 적절하게 실시하기 위한 반복자를 취득한다.


HashSet - 대표적인 set의 구현 클래스로 요소의 해시를 갖고 고속으로 값을 검색할수 있다.

LinkedHashSet - 앞뒤로의 참조를 갖음으로써 순서를 유지하는 클래스, 요소의 추가선수를 유지하고 싶을 때 사용한다.

TreeSet - 자동으로 요소의 정렬를 실시하는 클래스 '지정한 값보다 큰 요소의 경우'등의 순서를 의식한 조작을 실시할 수 있다.


package com.eeswk;


import java.util.ArrayList;

import java.util.Arrays;

import java.util.HashSet;

import java.util.List;

import java.util.Set;


public class SetSample {


public static void main(String[] args) {

Set<Integer> set = new HashSet<>();

//컬렉션을 Set로 변환

List<Integer> integerLiset = new ArrayList<>();

Set<Integer> integerSet = new HashSet<>(integerLiset);

List<Integer> integerLiset2 = Arrays.asList(1, 10, 2, 4, 7, 3, 1);

System.out.println(integerLiset2);

Set<Integer> integerSet2 = new HashSet<>(integerLiset2);

System.out.println(integerSet2);

//배열을 Set으로 변환

Integer[] integerArray = new Integer[]{1, 6, 1, 2, 7, 3};

List<Integer> integerList3 = Arrays.asList(integerArray);

Set<Integer> integerSet3 = new HashSet<>(integerList3);

System.out.println(integerSet3);

Set<String> names = new HashSet<>();

names.add("은유");

names.add("소유");

names.add("예음");


System.out.println(names.toString());

}


}


HashSet 클래스

해시값을 계산하여 내부의 해시테이블이라는 테이블에 값을 보관하는 방법으로 요소를 관리한다.

요소의 위치를 해시에 의해 계산되기 때문에 고속으로 처리할 수 있다.

단 요소를 추가할 때 해시 테이블의 크기를 확장하는 처리와 요소에 대한 액세스가 동시에 진행되는 경우 무한 루프에 빠지는 경우가 있다.

따라서 HashSet에 대해 여러 스레드에 동시에 액세스하는 경우 

- 여러 스레드에 동시에 액세스할 수 없도록 synchronized 등으로 동기화한다.

- 여러 스레드에서 액세스되어도 안전하게 사용할 수 있게 ConcurrentHashMap에서 Set를 작성하여 사용한다.

HashSet에서는 요소의 추가 순서는 유지 되지 않는다.

반복자로 요소에 대한 반복처리를 실시할 때 일반적으로 HashSet에 추가된 순서와는 다른 순서로 값이 취득된다.


LinkedHashSet

HashSet클래스로 유지하고 있는 요소에 요소사이의 링크를 부가하여 관리하는 클래스다.

HashSet과 동일하게 해시 테이블에 요소를 보관하고 있지만 List의 LinkedList처럼 요소 자신이 앞뒤의 정보도 갖고 있다.

HashSet의 서브 클래스다. 따라서 특징은 HashSet과 동일하지만 요소 자체가 앞뒤 정보를 가지고 있기 때문에 요소를 추가한 순서가 유지된다.

추가한 순서가 유지되므로 반복자에서 요소에 대해 반복처리를 할때 추가된 순서대로 요소가 취득된댜.

단, 동일한 값을 여러개 추가하는 경우 두번째 이후의 요소는 추가되지 않는다.(이미 추가된 요소는 덮어쓰지 않는다.)

요소 추가/삭제에 대해서는 HashSet과 비교하면 요소 사이의 링크의 교체가 필요한 만큼 LinkedHashSet의 경우 성능이 약간 떨어지지만 차이가 거의 없다.

iterator나 for-each문을 사용한 루프는 요소 간의 링크를 따라 요소를 열거하기 때문에 LinkedList와 거의 동일한 성능이 나온다. HashSet의 루프에서는 해시 테이블 내의 요소를 열거하는데 해시가 중복되는 요소가 보관되어 있으면 그 부분에 대해서 추가적으로 리스트의 열거가 이루어지기 때문에 성능이 저하된다. 따라서 요소의 열거에 대해서는 일반적으로 LinkedHashSet 속도가 빠르다.


TreeSet

키 값을 바탕으로 이진 탐색트리의 알고리즘의 의해 요소가 정렬하는 클래스다.

정렬은 요소를 추가할 때 이뤄지고 TreeSet의 내부에서는 요소가 정ㄹ려된 상태로 유지된다.

TreeSet에서는 다른 Set에서 할수 없는 "00이상 00이하인 요소의 취득"이나 "00보다 큰 가장 가까운 요소의 취득"등 크고 작음을 의식한 값의 취득을 할수 있다.

또한 요소의 추가/삭제/검색은 내부의 이진 탐색트리 구조를 추적해야 하기 때문에 최악의 계산량으로 O(log n)의 시간이 필요하다.

빈번하게 요소의 추가/삭제/검색을 실시할 경우는 HashSet 등의 Set에 비해 처리 시간의 차가 현저하게 나타난다.


Map과 Set의 관계

Map은 키와 값의 대응을 유지하는 클래스 

Set 요소의 집합을 나타내는 클래스

Map에서 키와 Set에서의 요소의 특성으로 Map의 키는 중복을 허용하지 않고 Set은 중복하는 요소를 보관하지 않는 특징이 있다.

이 특징을 이용하여 실은 Set의 내부에 Map이 존재한다.

그래서 Set에 추가된 요소들은 Map 키로 유지된다.

Map의 기능을 잘 활용한 효율적인 구현 방법이다.

또한 Set의 내부에서 유지하는 Map의 값에 해당하는 부분은 null 이외라면 뭐든지 좋기 때문에 일반적으로 boolean 타입에 "TRUE"가 보관된다. boolean 값은 사용되지 않는다.



Map으로부터 Set을 만들수 있기 때문에 ConcurrentHashSet이 없다.

Set<Integer> concurrentHashSet = Collections.newSetFromMap(new ConcurrentHashMap<Integer, Boolean>());


Queue 인터페이스

큐란 선입선출이라는 방법으로 값을 넣고 빼는 컬렉션이다.

내부에서 List또는 배열을 갖고 있어 '값을 추가한 순서와 동일한 순서로 값을 취득하기'라는 특성을 갖고 있다.

Queue에서는 offer 메서드로 값을 추가하고 poll메서드 또는 peek 메서드로 값을 취득한다.

값을 취득이후

poll => 값을 삭제

peek => 값을 삭제안함


peek을 호출하면 동일한 값이 나온다.


Queue는 데이터의 일시 보관 장소로 자주 사용된다.

그 경우 데이터를 보관하는 처리와 데이터를 추출하는 처리는 별개의 스레드로 실시해야 한다.

왜냐하면 필연적으로 멀티 스레드를 고려할 필요가 있기 때문이다.

Queue를 사용할때는 BlockingQueue의 구현인 ArrayBlockingQueue이나 LinkedBlockingQueue 또는 ConcurrentLinkedQueue 등 스레드 세이프인 Queue을 사용하도록 한다.


package com.eeswk;


import java.util.Queue;

import java.util.concurrent.ArrayBlockingQueue;


public class QueueSample {


public static void main(String[] args) {

Queue<Integer> queue = new ArrayBlockingQueue<>(10);

queue.offer(1);

queue.offer(3);

queue.offer(4);

System.out.println(queue.poll());

System.out.println(queue.poll());

queue.offer(6);

System.out.println(queue.peek());

System.out.println(queue.peek());

}

}


양방향 Queue

Deque 인터페이스

쌍방향이라는 의미는 Deque 내부에서 유지하고 있는 List 또는 배열에 대해서 앞에서부터든 뒤에서부터든 값의 추가나 삭제가 가능하다는 의미이다.

값을 추가 => offerFirst / offerLast

값을 취득 => pollFirst / pollLast


package com.eeswk;


import java.util.Deque;

import java.util.concurrent.LinkedBlockingDeque;


public class DequeSample {


public static void main(String[] args) {

Deque<Integer> deque = new LinkedBlockingDeque<>(10);

deque.offerFirst(1);

deque.offerFirst(3);

deque.offerLast(4);

deque.offerLast(5);

System.out.println(deque.pollLast());

System.out.println(deque.pollLast());

System.out.println(deque.pollFirst());


}


}


출처: 자바 마스터북

반응형

'JAVA > JAVA 기초' 카테고리의 다른 글

문자열관련  (0) 2018.10.22
예외 관련  (0) 2018.10.21
자바 배열관련  (0) 2018.10.13
자바 타입관련  (0) 2018.10.13
자바 기본형 참조형 클래스 관련  (0) 2018.10.12