어떤 Java Collection을 사용해야합니까?


127

이 질문 에서 C ++ 11에서 표준 라이브러리 컨테이너를 효율적으로 선택하려면 어떻게해야합니까? C ++ 컬렉션을 선택할 때 사용하는 편리한 순서도입니다.

나는 이것이 어떤 컬렉션을 사용 해야하는지 잘 모르는 사람들에게 유용한 리소스라고 생각했습니다. 그래서 Java에 대한 비슷한 순서도를 찾으려고했지만 그렇게 할 수 없었습니다.

사람들이 Java로 프로그래밍 할 때 사용할 올바른 컬렉션을 선택하는 데 도움이되는 어떤 리소스와 "치트 시트"가 있습니까? 사람들이 사용해야 할 List, Set 및 Map 구현을 어떻게 알 수 있습니까?


Java Generics and Collections (Naftalin & Wadler) 책에는 이에 관한 장이 있습니다.
Christophe Roussy

답변:


292

비슷한 플로우 차트를 찾을 수 없었기 때문에 직접 만들었습니다.

이 플로우 차트는 동기화 된 액세스, 스레드 안전성 등 또는 레거시 콜렉션과 같은 것을 시도하고 다루지 않지만 3 표준 세트 , 3 표준 및 2 표준 목록 은 다루고 있습니다.

여기에 이미지 설명을 입력하십시오

이 이미지는이 답변을 위해 작성되었으며 Creative Commons Attribution 4.0 국제 라이센스에 따라 라이센스가 부여됩니다 . 가장 간단한 속성은이 질문 또는이 답변에 연결하는 것입니다.

기타 자료

아마도 가장 유용한 다른 참고 자료는 각 콜렉션 을 설명하는 오라클 문서의 다음 페이지입니다 .

해시 셋과 트리 셋

사용시기 HashSet또는 TreeSet여기에 대한 자세한 설명이 있습니다 : Hashset vs Treeset

ArrayList와 LinkedList

자세한 토론 : ArrayList에서 LinkedList를 언제 사용해야합니까?


좋은! 그러나 나는 당신에 동의합니다 LinkedListArrayList결정. 첫째, 목록의 크기가 큰 경우 LinkedList바람직합니다. LinkedList요소 당 오버 헤드가 있으므로 메모리 소비 측면에서보다 무질서하게 악화됩니다 ArrayList. 또한, 대부분의 액세스가리스트의 끝에있는 경우, ArrayList상수-시간 랜덤 요소 액세스를 제공하므로 바람직합니다. na 의 th 요소에 액세스 하는 LinkedList것은 O(n)작업입니다. ... 실제로, 링크 된 목록을 사용하기로 한 결정은 항상 "아니오" .
매트 볼

2
@MattBall 대부분 동의합니다. 그러나 Java LinkedList는 이중 연결 목록이므로 시작과 끝의 액세스가 모두 빠릅니다. 당신은 내가 사용하기를 권장하기 전에 세 가지 질문 모두 위에있는 지점 LinkedList중 예에 대답해야한다는 것을 알 것입니다. 즉, 나는 대부분의 경우 대답이 아니오라는 것에 동의합니다. 목록 영역의 끝에 항목을 지속적으로 추가하고 제거하는 대기열 및 대기열과 같은 것들에 대한 유스 케이스입니다 LinkedList.
Tim B

@MattBall 메모리 사용량은 LinkedList요소 당 더 많은 메모리를 사용 하지만 메모리를 ArrayList해제하지 않기 때문에 훨씬 까다로운 상황 입니다. 즉, 때때로 크기가 커지지 만 일반적으로 작은 목록이 있으면 ArrayList메모리 성능이 저하됩니다. List자체 의 메모리 오버 헤드 는 일반적으로 포함 된 요소 의 메모리 오버 헤드 와 비교하여 (항상은 아니지만) 작습니다.
Tim B

Map<K,V>java.util.collection
Mehraj Malik

@MehrajMalik 흠, 라벨이 모호합니다. java.util 내의 Collection을 의미했습니다. 즉, java.util. * 여기에 컬렉션 이름 삽입 *
Tim B

66

주요 비 동시 비 동기화 컬렉션 요약

Collection: "elements"라고하는 정렬되지 않은 "bag"아이템을 나타내는 인터페이스. "다음"요소는 정의되지 않습니다 (무작위).

  • Set: Collection중복이없는를 나타내는 인터페이스 입니다.
    • HashSet:에 Set의해 지원됩니다 Hashtable. 순서가 중요하지 않은 경우 가장 빠르고 작은 메모리 사용.
    • LinkedHashSet하십시오 HashSet에 연관 요소에 링크 된리스트가 추가 신청서 . "다음"요소는 가장 최근에 삽입 된 요소입니다.
    • TreeSet: Set요소가 주문되는 위치Comparator (일반적으로 자연 순서 )로 정렬 됩니다. 가장 느리고 가장 큰 메모리 사용량이지만 비교기 순서에 필요합니다.
    • EnumSet: 매우 빠르고 효율적 Set 단일 열거 형 유형에 맞게 사용자 정의됩니다.
  • List:를 나타내는 인터페이스 Collection 요소가 정렬되어 있고 각각의 위치를 ​​나타내는 숫자 색인이 . 여기서 0은 첫 번째 요소이며 (length - 1)마지막 요소 입니다.
    • ArrayList: List배열 의 지원을받으며, 배열의 길이는 요소 수 (목록의 "크기")만큼 큰 길이 ( "용량")입니다. 크기가 용량을 초과하면 ( (capacity + 1)-th요소가 추가 될 때 ) 새로운 용량으로 어레이가 재생성됩니다.이 재생산 (new length * 1.5)은를 사용하기 때문에 빠릅니다 System.arrayCopy(). 요소를 삭제 및 삽입 / 추가하려면 인접한 모든 요소 (오른쪽)를 해당 공간으로 또는 밖으로 이동해야합니다. (element-zero-address + desired-index * element-size)위치를 찾기 위해 계산 만하면되므로 모든 요소에 빠르게 액세스 할 수 있습니다. 대부분의 상황에서 에서 ArrayLista보다 a가 선호 LinkedList됩니다.
    • LinkedList: List각각의 "이전"및 "다음"이웃에 연결된 일련의 객체로 뒷받침됩니다. A는 LinkedList또한이다 QueueDeque. 요소 액세스는 첫 번째 또는 마지막 요소에서 시작하여 원하는 색인에 도달 할 때까지 순회합니다. 삽입 및 삭제, 순회를 통해 원하는 색인에 도달 하면 즉시 인접한 링크 만 새 요소를 가리 키거나 지금 삭제 된 요소를 무시하도록 다시 매핑하는 것이 쉽지 않습니다.
  • Map: Collection각 요소에 식별 "키"가 있는 위치를 나타내는 인터페이스입니다 . 각 요소는 키-값 쌍입니다.
    • HashMap: Map키가 정렬되지 않고로 백업되는 위치입니다 Hashtable.
    • LinkedhashMap: 키는 삽입 순서에 따라 정렬됩니다 .
    • TreeMap: Map키를 주문한 곳Comparator (일반적으로 자연 순서대로) 주문됩니다.
  • Queue:를 나타내는 인터페이스 Collection 요소가 일반적으로 한쪽 끝에 추가되고 다른 쪽에서 제거되는 위치 (FIFO : 선입 선출).
  • Stack:를 나타내는 인터페이스 Collection 요소가 일반적으로 같은 끝 (LIFO : last-in, first-out)에서 추가 (푸시) 및 제거 (팝업)되는 위치 .
  • Deque: "더블 엔드 큐"의 약자이며 일반적으로 "데크"로 발음됩니다. 일반적으로 양쪽 끝에 만 추가되고 읽은 링크 된 목록 (가운데 아님).

기본 수집 다이어그램 :

도표

ArrayListand 를 사용하여 요소 삽입을 비교 LinkedList:

도표


2
어느 곳이든 얻을 수있는 짧은 여름에 최고 :)
roottraveller

11

더 간단한 그림도 있습니다. 의도적으로 단순화되었습니다!

  1. 콜렉션 은 "요소"(같은 유형)라는 데이터를 보유하는 모든 것입니다. 더 구체적인 것은 없습니다.

  2. 목록 색인입니다 각 요소에 데이터 콜렉션입니다. 배열과 비슷하지만 더 유연합니다.

    목록의 데이터는 삽입 순서를 유지합니다.

    일반적인 작업 : n 번째 요소를 가져옵니다.

  3. Set elements of bag이며 , 각 요소는 한 번만입니다 (요소는equals() 방법을 .)

    집합의 데이터는 주로 어떤 데이터가 있는지 알기 위해 저장됩니다 .

    일반적인 작업 : 요소가 목록에 있는지 알려줍니다.

  4. Map 은 List와 비슷하지만 정수 인덱스로 요소에 액세스하는 대신객체 인 key로 액세스합니다. PHP의 배열처럼 :)

    지도의 데이터는 키로 검색 할 수 있습니다.

    일반적인 작업 : ID로 요소를 가져옵니다 (여기서 ID는 intList의 경우 뿐만 아니라 모든 유형 임).

차이점들

  • 설정 및지도 :에서 키로 지도에서 데이터 를 직접 검색하도록 설정합니다 .

  • List and Map : List에서 int색인 (List의 위치)으로 요소에 액세스 하는 반면, Map에서 어떤 유형의 os (일반적으로 ID)로 키에 의해 요소에 액세스합니다 .

  • 목록 및 설정 : 목록에있는 요소는 자신의 위치에 구속되어 세트의 요소는 단지 "존재"이다 (홍보 없음) 및 고유 (의 의미로 동안 중복 될 수있다 equals(), 또는 compareTo()에 대한 SortedSet)


1

간단합니다 : 키로 매핑 된 값을 저장 해야하는 경우 Map 인터페이스로 이동하십시오. 그렇지 않으면 중복 될 수있는 값에 List를 사용하고 컬렉션에서 중복 값을 원하지 않으면 Set 인터페이스를 사용하십시오.

흐름도 등을 포함한 http://javatutorial.net/choose-the-right-java-collection에 대한 완전한 설명은 다음과 같습니다.


1

지도

를 선택하면 Map이 표를 Java 11과 함께 제공되는 10 가지 구현 각각의 기능을 요약하여 만들었습니다.

기능을 비교 한 Java 11의 맵 구현 표



-2

어떤 Java Collection을 사용해야합니까?

해결하려는 문제 또는 요구 사항에 따라 다릅니다.

예 :

  1. 요소를 저장하는 동안 요소를 정렬 하시겠습니까? 해시 세트
  2. (키, 값) 쌍을 저장 하시겠습니까? 해시 맵
  3. 삽입 할 때 요소의 순서를 유지 하시겠습니까? 배열 목록, 연결 목록
  4. (키, 값) 쌍의 키를 정렬 하시겠습니까? - 강력한 텍스트
  5. 문제를 해결하기 위해 스택을 구현 하시겠습니까? - 스택
  6. FIFO (선입 선출) 액세스를 원하십니까? - 대기열
  7. UNIQUE 요소 만 저장 하시겠습니까? - 해시 세트
  8. (Key, Value)를 저장하는 동안 키를 "Null"로 허용 하시겠습니까? - 해시 맵
  9. (Key, Value) 쌍에 NULL 값을 원하지 않습니까? 해시 테이블

항목 4의 강력한 텍스트ConcurrentSkipListMap (K, V) 로 대체 되었음에도 불구 하고이 답변은 Tim B의 결정 그래프 와 aliteralmind의 "짧은 목록 설명"에 어떤 영향을 미칩니 까?
greybeard

첫 번째 요점 인 HashSet은 데이터를 정렬하지 않으며 심지어 삽입 순서가 유지되지 않습니다. 당신은 TreeSet의로 변경해야합니다
Saurabh 슈라에게
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.