Java의 컬렉션은 주로 두 부분으로 집중되어 있습니다. 하나는 java.util 패키지에 있고 다른 하나는 java.util.concurrent에 있습니다. 후자는 전자를 기반으로 하며 동기화 기능을 구현하는 일부 컬렉션을 정의합니다.
이 기사에서는 주로 java.util의 다양한 컬렉션 개체에 중점을 둡니다. Java의 컬렉션 개체는 대략 List, Set 및 Map의 세 가지 범주로 나눌 수 있습니다. 해당 UML 다이어그램은 다음과 같습니다(java.util 아래의 대부분의 컬렉션 개체 포함).
컬렉션 개요
Java 컬렉션의 List 및 Set은 모두 Collection에서 제공됩니다. 이는 컬렉션에 일반적으로 필요한 작업을 포함하는 좋은 시작점입니다.
요소 추가: add/addAll
컬렉션 지우기: 지우기
요소 제거: 제거/제거모두
컬렉션에 요소가 포함되어 있는지 확인: contain/containsAll
컬렉션이 비어 있는지 확인: isEmpty
컬렉션의 요소 수 계산: 크기
컬렉션을 배열로 변환: toArray
반복자 가져오기: 반복자
간단한 예를 살펴보겠습니다. 다음 코드는 요소가 무작위로 생성된 정수인 컬렉션을 반환합니다.
반품수거;
}
1) 반복자를 사용하여 컬렉션을 탐색합니다. 위에서 Collection 인터페이스를 설명할 때 언급했듯이 모든 컬렉션에는 컬렉션을 탐색하는 데 사용할 수 있는 반복자가 있습니다.
Java의 목록은 배열의 효과적인 확장입니다. 제네릭이 사용되지 않는 경우 모든 유형의 요소를 보유할 수 있습니다. 제네릭에서 지정한 유형의 요소만 보유할 수 있습니다. 배열에 비해 List의 용량은 동적으로 확장될 수 있습니다.
목록의 요소는 반복될 수 있으며 내부 요소는 "순서 지정"됩니다. 여기서 "순서 지정"은 정렬을 의미하는 것이 아니라 컬렉션에서 요소의 위치를 지정할 수 있음을 의미합니다.
List에서 일반적으로 사용되는 컬렉션 개체에는 ArrayList, Vector 및 LinkedList가 포함됩니다. 전자는 배열을 기반으로 저장되고 후자는 연결된 목록을 기반으로 저장됩니다. 그 중 Vector는 스레드로부터 안전하고 나머지 두 개는 스레드로부터 안전하지 않습니다.
제네릭이 사용되는 경우에도 목록에는 null이 포함될 수 있습니다.
ArrayList는 가장 일반적으로 사용되는 컬렉션 개체일 수 있습니다. 위의 예제 코드에서는 이를 사용하여 Collection 개체를 인스턴스화하므로 여기서는 자세히 설명하지 않겠습니다.
벡터
Vector의 예는 다음과 같습니다. 먼저 Vector를 생성하고 출력하는 방법을 살펴보겠습니다.
[9, 29, 32, 54, 12]
벡터의 크기는 3입니다.
[29, 32, 54]
LinkedList는 연결된 목록을 사용하여 데이터를 저장합니다.
출력은 다음과 같습니다.
null
null
null
연결리스트의 크기는 8이다
[100, 84, 19, 57, 68, 26, 27, 47]
Set은 List와 유사하며 둘 다 단일 요소를 저장하는 데 사용되며 개별 요소의 수는 불확실합니다. 그러나 Set에는 중복된 요소가 포함될 수 없습니다. 두 개의 동일한 요소가 Set에 삽입되면 후자의 요소는 삽입되지 않습니다.
Set은 크게 unsorted Set과 sorted Set으로 나눌 수 있는데, Unsorted Set에는 HashSet과 LinkedHashSet이 있고, sorted Set은 주로 TreeSet을 가리킨다. 그 중 HashSet과 LinkedHashSet에는 null이 포함될 수 있습니다.
해시세트
HashSet은 스레드로부터 안전하지 않은 해시 테이블을 기반으로 하는 컬렉션입니다.
기본적으로 Vector의 첫 번째 예와 동일한 다음 예를 살펴보겠습니다.
for (int i = 0; i < 3; i++)
{
set.add(new Integer(100));
}
set.add(null);
System.out.println("세트의 크기는 " + set.size());
System.out.println(세트);
}
classMyInteger
{
개인 정수 값;
public MyInteger(정수값)
{
this.value = 값;
}
공개 문자열 toString()
{
return String.valueOf(값);
}
공개 int hashCode()
{
1을 반환합니다.
}
공개 부울은 같음(객체 obj)
{
사실을 반환;
}
}
다음은 해당 테스트 방법입니다.
for (int i = 0; i < 3; i++)
{
set.add(new MyInteger(100));
}
System.out.println("세트의 크기는 " + set.size());
System.out.println(세트);
}
TreeSet은 정렬을 지원하는 Set이며 상위 인터페이스는 SortedSet입니다.
먼저 TreeSet의 기본 작업을 살펴보겠습니다.
무작위 r = 새로운 무작위();
for (int i = 0; i < 5; i++)
{
set.add(new Integer(r.nextInt(100)));
}
System.out.println(세트);
System.out.println(set.first());
System.out.println(set.last());
System.out.println(set.descendingSet());
System.out.println(set.headSet(new Integer(50)));
System.out.println(set.tailSet(new Integer(50)));
System.out.println(set.subSet(30, 60));
System.out.println(set.floor(50));
System.out.println(set.ceiling(50));
}
[53, 49, 48, 42, 8]
[8, 42, 48, 49]
[53]
[42, 48, 49, 53]
다음으로 먼저 Integer를 재정의합니다.
공개 MyInteger2(int 값)
{
this.value = 값;
}
공개 int 비교(객체 arg0)
{
MyInteger2 임시 = (MyInteger2)arg0;
if (temp == null) -1을 반환합니다.
if (임시값 > this.값)
{
1을 반환합니다.
}
else if (temp.value < this.value)
{
-1을 반환합니다.
}
0을 반환합니다.
}
공개 부울은 같음(객체 obj)
{
return CompareTo(obj) == 0;
}
공개 문자열 toString()
{
return String.valueOf(값);
}
}
맵은 "키-값 쌍"을 저장합니다. Java에는 정렬된 맵과 정렬되지 않은 맵이 있으며, 정렬된 맵에는 HashMap, Hashtable 및 LinkedHashMap이 포함됩니다.
정렬되지 않은 지도
HashMap과 Hashtable은 모두 Hash 테이블 형식으로 저장됩니다. HashMap은 스레드로부터 안전하지 않지만 Hashtable은 HashMap을 Hashtable의 "간단한" 버전으로 간주할 수 있습니다.
HashMap은 키 또는 값에 관계없이 null을 저장할 수 있습니다. 해시테이블은 null을 저장할 수 없습니다.
HashMap이나 Hashtable에 관계없이 생성자를 관찰하면 그것이initialCapacity와 loadFactor라는 두 개의 매개변수를 가질 수 있다는 것을 알 수 있습니다. 기본적으로,initialCapacity는 16이고 loadFactor는 0.75입니다. 이는 Hash 테이블에 저장할 수 있는 요소 수와 관련이 있습니다. 요소 수가initialCapacity*loadFactor를 초과하면 rehash 메소드가 트리거되어 해시 테이블을 확장합니다. 너무 많은 요소를 삽입해야 한다면 이 두 매개변수를 적절하게 조정해야 합니다.
먼저 HashMap의 예를 살펴보겠습니다.
map.put(new Integer(1), "a");
map.put(new Integer(2), "b");
map.put(new Integer(3), "c");
System.out.println(map);
System.out.println(map.entrySet());
System.out.println(map.keySet());
System.out.println(map.values());
}
map.put(null, null);
map.put(null, null);
map.put(new Integer(4), null);
map.put(new Integer(5), null);
System.out.println(map);
System.out.println(map.entrySet());
System.out.println(map.keySet());
System.out.println(map.values());
}
table.put(new Integer(1), "a");
table.put(new Integer(2), "b");
table.put(new Integer(3), "c");
System.out.println(테이블);
System.out.println(table.entrySet());
System.out.println(table.keySet());
System.out.println(table.values());
}
개인 정적 무효 hashTableTest2()
{
Map<Integer,String> table = new Hashtable<Integer, String>();
table.put(null, null);
table.put(null, null);
table.put(new Integer(4), null);
table.put(new Integer(5), null);
System.out.println(테이블);
System.out.println(table.entrySet());
System.out.println(table.keySet());
System.out.println(table.values());
}
Sorting Map은 주로 TreeMap을 의미하며 요소 추가, 삭제, 검색 시 O(log(n))의 시간 복잡도를 갖습니다. 스레드로부터 안전하지 않습니다.
그 특성은 TreeSet과 매우 유사하므로 여기서는 자세히 설명하지 않겠습니다.