1. Java의 컬렉션
Java의 컬렉션 클래스는 Java 프로그래밍에서 가장 자주 사용되고 가장 편리한 클래스입니다. 컨테이너 클래스로서 컬렉션 클래스는 모든 유형의 데이터를 저장할 수 있으며 물론 지정된 유형을 제네릭과 함께 저장할 수도 있습니다 (그러나 제네릭은 컴파일 기간 동안 만 유효하며 런타임에 지워집니다). 컬렉션 클래스에 저장되는 것은 객체 자체에 대한 참조가 아니라 객체에 대한 참조 일뿐입니다. 수집 클래스의 용량은 작동 중에 동적으로 확장 될 수 있으며, 컬렉션의 노조 및 교차로를 찾는 것과 같은 많은 편리한 방법을 제공합니다.
2. 수집 클래스 구조
Java의 컬렉션에는 연결된 목록, 대기열, 해시 테이블 등과 같은 여러 데이터 구조가 포함됩니다. 클래스의 상속 구조 측면에서 두 가지 범주로 나눌 수 있습니다. 하나는 컬렉션 인터페이스에서 상속됩니다. 이 유형의 컬렉션에는 목록, 세트 및 큐와 같은 컬렉션 클래스가 포함됩니다. 다른 클래스는 맵 인터페이스에서 상속되며 주로 해시 테이블과 관련된 컬렉션 클래스가 포함됩니다. 이 두 범주의 상속 구조 다이어그램을 살펴 보겠습니다.
1. 목록, 세트 및 대기열
그림의 녹색 점선은 구현을 나타내고, 녹색 실선은 인터페이스 사이의 상속을 나타내고, 파란색 실선은 클래스 간의 상속을 나타냅니다.
(1) 목록 : ArrayList 및 LinkedList를 포함한 더 많은 목록을 사용합니다. 이 둘 사이의 차이점은 또한 매우 명백하며 이름에서 볼 수 있습니다. 기본 Arraylist는 어레이를 통해 구현되므로 임의의 액세스 속도는 비교적 빠르지 만, 자주 추가 및 삭제가 필요한 경우 효율은 상대적으로 낮습니다. LinkedList의 경우 기본 레이어는 링크 된 목록을 통해 구현되므로 추가 및 삭제 작업이 완료되기 쉽지만 임의 액세스 효율은 비교적 낮습니다.
먼저 두 가지의 삽입 효율을 살펴 보겠습니다.
package com.paddx.test.collection; import java.util.arraylist; import java.util.linkedlist; public class listtest {public static void main (string [] args) {for (int i =; i} long start = system.currenttimillis (); 링크드 레터> LinkedList <integer> (); for (int i =; i <; i ++) {linkedList.Add (, i);} long end = system.currentTimeMillis (); System.out.println (END -Start); ArrayList <integer> arrayList <integer> (); i =; i <; i ++) {arraylist.add (, i);} system.out.println (System.CurrentTimeMillis () - end);}}지역 실행 결과는 다음과 같습니다.
스물 셋
1227
이 경우 Linkedlist의 삽입 효율이 ArrayList의 삽입 효율보다 훨씬 높다는 것을 알 수 있습니다. 물론 이것은 비교적 극단적 인 상황입니다. 둘 사이의 무작위 액세스 효율을 비교해 봅시다.
package com.paddx.test.collection; import java.util.arraylist; import java.util.linkedList; import java.util.random; public static void main (public static void main (string [] args)) {random random = new random (); for (int i =; i <; i ++) {inte <integer> linkedList <integer> (); for (int i =; i <; i ++) {linkedList.Add (i);} arrayList <integer> arrayList = new ArrayList <integer> (); for (int i =; i <; i ++) {arraylist.add (i);} long start = system.currenttimeMillis (); for (int i =; i <; i ++) {int j = random.nextint (i+); int k = linkedList.get (j);} long end = system.currentTimeMillis (); System.out.println (end -start); for (int i =; i <; i ++) {int j = random.nextint (i+); int k =. ArrayList.get (j);} system.out.println (System.CurrentTimeMillis () -End);}}내 실행 결과는 다음과 같습니다.
5277
6
ArrayList의 랜덤 액세스 효율은 LinkedList보다 몇 배 높은 순서입니다. 이 두 코드를 통해 LinkedList와 ArrayList의 차이점과 적응 시나리오의 차이점을보다 명확하게 알 수 있어야합니다. Vector의 경우, Arraylist의 스레드 안전 버전이며 스택은 스택 데이터 구조에 해당합니다. 이 두 가지는 덜 자주 사용되므로 여기서 예를 들어 보이지 않습니다.
(2) 대기열 : 일반적으로 LinkedList를 사용하여 직접 수행 할 수 있습니다. 또한 링크드리스트가 Deque에서 상속하는 위의 클래스 다이어그램에서 볼 수 있으므로 LinkedList는 이중 종말 큐의 기능을 갖습니다. PriorityQueue는 각 요소에 대한 우선 순위를 제공하며 우선 순위가 높은 요소는 대기열에서 우선 순위를 부여합니다.
(3) 세트 : 세트와 목록의 주요 차이점은 세트가 요소를 반복 할 수 없으며 목록을 반복 할 수 있다는 것입니다. 요소의 반복을 판단하려면 오브젝트의 해시 메소드와 동등한 방법을 기반으로 결정해야합니다. 이것이 바로 우리가 일반적으로 해시 코드 메소드와 컬렉션의 요소 클래스에 대한 방법을 무시하는 이유이기도합니다. 세트와 목록의 차이점과 해시 코드 메소드의 역할과 동등한 방법의 역할을 보자.
package com.paddx.test.collection; import java.util.arraylist; import java.util.hashset; import java.util.set; public class settest {public static void main (문자열 [] args) {person p1 = 새로운 사람 ( "lxp", 10); 새로운 사람 ( "lxp", 10); person ( "lxp", 20); arraylist <person> list = new arraylist <person> (); list.add (p1); system.out.println ( "-------------"); list.add (p2); system.out.println ( "--------------"); List.out.out.out.out.out.out.out.println ( " + list.size ()); system.out.println ( "--------------"; set <person> set = new Hashset <person> (); set.add (p1); system.out.println ( "------------"); Set.Add (p2); System.out.println ( "------------"); System size = "+set.size ());} 정적 클래스 사람 {개인 문자열 이름; 개인 int 연령; 공개 사람 (문자열 이름, int age) {this.name = name; this.age = age;}@reveridepublic boolean equals (object o) {system.out.println ("call equals (); name = "+name); ! = O.getClass ()) return false; person person = (person) o; return name.equals (person.name);}@atriadepublic int hashcode () {system.out.println ( "call hashcode (), age ="+age); return age;}}} 위 코드의 실행 결과는 다음과 같습니다.
------------
------------
목록 크기 = 3
---- 선을 분할 ----
hashcode (), age = 10을 호출하십시오
------------
hashcode (), age = 10을 호출하십시오
Call Equals (); name = lxp
------------
hashcode (), age = 20을 호출하십시오
세트 크기 = 2
결과에서 요소가 목록에 추가 될 때 추가 작업이 수행되지 않고 반복 될 수 있습니다. 세트에 가입하기 전에 먼저 해시 코드 메소드를 실행해야합니다. 반환 된 값이 이미 세트에 존재하는 경우 계속해서 Equals 메소드를 실행해야합니다. Equals 메소드에 의해 반환 된 결과가 사실이라면, 요소가 이미 존재하고 기존 요소에 의해 새 요소가 덮어 쓸 것임을 증명합니다. 반환 된 해시 코드 값이 다른 경우 세트를 직접 추가합니다. 컬렉션의 요소의 경우 해시 코드 값이 다른 요소의 경우 불평등해야하지만 해시 코드 값이 동일 할 수없는 요소의 경우 동일 할 수 있습니다.
Hashset과 Linkedhashset의 차이점은 후자가 세트에 삽입 된 요소의 순서가 출력 순서와 일치하도록 보장 할 수 있다는 것입니다. Tresset의 차이점은 정렬이 비교기에 정렬되어 기본적으로 자연스럽게 문자 순서로 오름차순으로 배열된다는 것입니다.
(4) 반복적 인 :이 그림에서 컬렉션 클래스가 반복적으로 상속되는 것을 알 수 있습니다. 이 인터페이스의 기능은 요소 트래버스를 제공하는 것입니다. 반복에는 반복자의 반복자가 포함되어 있으며 소스 코드는 다음과 같습니다. 반복자 모드에 익숙하다면 이해하기 쉽습니다.
public interface iterator <e> {boolean hasnext (); e next (); void remove ();}2.지도 :
MAP 유형 수집의 가장 큰 장점은 검색 효율이 비교적 높고 O (1)의 시간 복잡성이 이상적으로 달성 될 수 있다는 것입니다. 가장 일반적으로 사용되는 맵은 해시 맵입니다. LinkedHashMap과 HashMap의 차이점은 전자가 세트에 삽입 된 요소의 순서가 출력 순서와 일치하도록 보장 할 수 있다는 것입니다. 이 두 가지와 Treemap의 차이점은 Treemap이 주요 값에 따라 정렬된다는 것입니다. 물론 기본 구현에는 필수적인 차이가 있습니다. 예를 들어, 해시 맵의 기본 층은 해시 테이블이고, Treemap의 기본 층은 나무입니다. 이제 Treemap과 LinkedHashmap의 차이점을 살펴 보겠습니다.
package com.paddx.test.collection; import java.util.iterator; import java.util.linkedhashmap; import java.util.map; import java.util.treemap; public static void main (string <args) {String> treemap = new trtemap <string, streemap <); linkedMap = new LinkedHashMap <string, String> (); treemap.put ( "b", null); treemap.put ( "c", null); treemap.put ( "a", null); for (iterator <string> iter = treemap.keyset (). iterator (); iter.hasnext ();) {system.out.println ( "treemap ="+iter.next ());} system.out.prin tln ( "------------------"); LinkedMap.put ( "b", null); linkedMap.put ( "c", null); linkedMap.put ( "a", null); (iterator <string> iter = linkedMap.keyset (). iterator (); iter.hasnext ();) {System.out.println ( "linkedHashMap ="+iter.next ());}}} 위의 코드를 실행하면 실행 결과는 다음과 같습니다.
treemap = a
Treemap = b
treemap = c
-----------------------------
LinkedHashMap = b
LinkedHashMap = c
LinkedHashMap = a
실행 결과에서 Treemap과 Linkedhashmap의 차이가 명확하게 보입니다. 전자는 문자열 정렬에 의해 출력되는 반면, 후자는 삽입 순서에 의해 출력됩니다. 신중한 독자들은 해시 맵과 트리 맵의 차이가 해시 세트와 트리 셋의 차이점과 일치한다는 것을 알 수 있습니다. 향후 소스 코드 분석을 수행 할 때 해시 세트와 트리 셋이 본질적으로 해시 맵과 트리 맵을 통해 각각 구현되므로 차이가 자연스럽게 동일하다는 것을 알 수 있습니다. Hashtable은 현재 거의 사용되지 않습니다. 해시 맵의 주요 차이점은 해시 테이블이 스레드 안전이지만 효율이 낮기 때문에 해시 맵이 일반적으로 사용된다는 것입니다. 다중 스레드 환경에서 Currenthashmap은 일반적으로 대신 사용됩니다.
3. 요약
이 기사는 Java Collection Framework와 상속 관계 전체 만 소개합니다. 위의 클래스 외에도 컬렉션은 컬렉션과 배열의 두 가지 도구 클래스를 제공합니다. 또한 컬렉션의 분류는 비교 및 비교기와 밀접한 관련이 있습니다. 후속 기사에서, JDK의 위에서 언급 한 클래스 구현 소스 코드는 자세히 분석됩니다.