java 집합 프레임워크의 체계 구조 상세 설명

최근 J2EE의 책에서 집합 프레임워크에 대한 좋은 설명문을 보았습니다. 선별하여 여러분과 공유하고 집합 프레임워크는 관리 대상의 집합 인터페이스와 클래스를 제공합니다.그것은 인터페이스, 클래스, 알고리즘을 포함하고 있으며, 다음은 그것의 각 구성 요소에 대한 설명입니다.Collection 인터페이스 Collection은 가장 기본적인 집합 인터페이스입니다. 하나의 Collection은 하나의 Object, 즉 Collection의 요소(Elements)를 대표합니다.일부 컬렉션은 같은 요소를 허용하고 다른 컬렉션은 안 됩니다.일부는 정렬할 수 있지만 다른 일부는 안 된다.Java SDK는 Collection에서 직접 상속되는 클래스를 제공하지 않습니다. Java SDK가 제공하는 클래스는 Collection에서 상속되는 "하위 인터페이스"예를 들어 List와 Set입니다.Collection 인터페이스를 실현하는 모든 클래스는 두 가지 표준 구조 함수를 제공해야 한다. 매개 변수가 없는 구조 함수는 빈 Collection을 만드는 데 사용되고, Collection 매개 변수가 있는 구조 함수는 새로운 Collection을 만드는 데 사용되며, 이 새로운 Collection은 들어오는 Collection과 같은 요소를 가진다.다음 구조 함수는 사용자가 Collection을 복사할 수 있도록 합니다.Collection의 모든 요소를 어떻게 훑어봅니까?Collection의 실제 형식이 어떻든지 간에,iterator () 방법을 지원합니다. 이 방법은 하나의 교체자를 되돌려줍니다. 이 교체자를 사용하면 하나하나 Collection의 모든 요소에 접근할 수 있습니다.전형적인 용법은 다음과 같다
 
Iterator it = collection.iterator(); //
while(it.hasNext()) {
Object obj = it.next(); //
}
Collection 인터페이스에서 파생된 두 인터페이스는 List와 Set입니다.List 인터페이스 List는 질서정연한 Collection입니다. 이 인터페이스를 사용하면 모든 요소가 삽입된 위치를 정확하게 제어할 수 있습니다.사용자는 Java의 배열과 유사한 인덱스 (요소가 List에 있는 위치, 배열 아래 표식) 를 사용하여 List의 요소에 액세스할 수 있습니다.다음 Set과 달리 List는 동일한 요소를 허용합니다.Collection 인터페이스에 필요한 iterator () 방법을 제외하고 List는 list Iterator () 방법을 제공하여 List Iterator 인터페이스를 되돌려줍니다. 표준 Iterator 인터페이스에 비해 List Iterator는add () 같은 방법이 많아서 추가, 삭제, 설정 요소를 허용하고 앞으로 또는 뒤로 훑어볼 수 있습니다.List 인터페이스를 실현하는 상용 클래스는 LinkedList, ArrayList, Vector 및 Stack입니다.LinkedList 클래스 LinkedList는 List 인터페이스를 실현하여null 요소를 허용합니다.또한 LinkedList는 추가 get,remove, insert 방법을 LinkedList의 첫 번째 부분이나 끝에 제공합니다.이러한 작업으로 LinkedList는 스택(stack), 대기열(queue) 또는 양방향 대기열(deque)로 사용할 수 있습니다.LinkedList에는 동기화 방법이 없습니다.여러 스레드가 하나의 List에 동시에 액세스하는 경우 액세스 동기화를 직접 수행해야 합니다.하나의 해결 방법은 List를 만들 때 동기화된 List:List list = Collections를 구성하는 것이다.synchronizedList(new LinkedList(...)); ArrayList 클래스 ArrayList는 가변 크기의 그룹을 실현합니다.이것은 null을 포함한 모든 요소를 허용합니다.ArrayList가 동기화되지 않았습니다.size, isEmpty, get, set 방법의 실행 시간은 상수입니다.그러나add 방법은 분담된 상수로 지출되고 n개의 요소를 추가하는 데 O(n)의 시간이 필요합니다.다른 방법의 운행 시간은 선형이다.각 ArrayList 인스턴스에는 요소를 저장하는 데 사용되는 배열의 크기인 용량(Capacity)이 있습니다.이 용량은 끊임없이 새로운 요소를 추가함에 따라 자동으로 증가할 수 있지만, 성장 알고리즘은 정의되지 않았다.대량의 요소를 삽입해야 할 때, 삽입하기 전에ensureCapacity 방법을 호출하여 ArrayList의 용량을 증가하여 삽입 효율을 높일 수 있습니다.LinkedList와 마찬가지로 ArrayList도 비동기적입니다.Vector 클래스 Vector는 Array List와 매우 유사하지만 Vector는 동기화됩니다.Vector에서 만든 Iterator는 Array List에서 만든 Iterator와 같은 인터페이스이지만 Vector가 동기화되어 있기 때문에 하나의 Iterator가 만들어지고 사용되고 다른 스레드가 Vector의 상태 (예를 들어 일부 요소를 추가하거나 삭제) 를 바꿉니다. 이 때 Iterator 방법을 호출할 때 Concurrent Modification Exception을 던져 이 이상을 포착해야 합니다.Stack 클래스 Stack은 Vector로부터 상속되어 후진적인 창고를 실현합니다.Stack은 Vector를 스택으로 사용할 수 있는 5가지 추가 방법을 제공합니다.기본적인push와pop방법,그리고peek방법은 창고의 원소를 얻고empty방법은 창고가 비어 있는지 테스트하고,search방법은 원소가 창고에 있는 위치를 측정합니다.Stack이 생성된 후 비어 있습니다.Set 인터페이스 Set은 중복된 요소를 포함하지 않는 컬렉션입니다. 즉, 임의의 두 요소 e1과 e2는 모두 e1이 있습니다.equals(e2) =false, Set에는 최대 null 요소가 있습니다.분명히 Set의 구조 함수는 제약 조건이 있습니다. 전송된 Collection 매개 변수는 중복된 요소를 포함할 수 없습니다.참고: 소프트 객체(Mutable Object)를 조심해야 합니다.세트의 가변 요소가 자신의 상태를 바꾸어 Object를 만드는 경우equals(Object) =true는 몇 가지 문제를 야기합니다.맵 인터페이스는 맵이 컬렉션 인터페이스를 계승하지 않았습니다. 맵은 키에서value에 대한 맵을 제공합니다.하나의 맵에 같은 키를 포함할 수 없습니다. 모든 키는value만 표시할 수 있습니다.맵 인터페이스는 3가지 집합의 보기를 제공합니다. 맵의 내용은 키 집합, 값 집합, 또는 키 집합으로 비칠 수 있습니다.Hashtable 클래스 Hashtable는 맵 인터페이스를 계승하여 키-value가 비치는 해시표를 실현합니다.비어 있지 않은 모든 대상은 키나value로 사용할 수 있습니다.데이터를 추가하려면put(key,value)를 사용하고, 데이터를 꺼내려면get(key)을 사용하며, 이 두 가지 기본 작업의 시간 비용은 상수입니다.Hashtable는 initialcapacity와loadfactor 두 개의 매개 변수를 통해 성능을 조정합니다.통상적으로 부족한loadfactor0.75는 시간과 공간의 균형을 비교적 잘 실현했다.loadfactor를 늘리면 공간을 절약할 수 있지만 그에 상응하는 검색 시간이 증가합니다. 이것은 get과put 같은 작업에 영향을 줄 수 있습니다.Hashtable을 사용하는 간단한 예는 다음과 같다. 1, 2, 3을 Hashtable에 넣으면 그들의 키는 각각'원','투','three'이다
 
Hashtable numbers = new Hashtable();
numbers.put(“one”, new Integer(1));
numbers.put(“two”, new Integer(2));
numbers.put(“three”, new Integer(3));
하나의 수를 꺼내야 한다. 예를 들어 2, 상응하는 키: Integer n = (Integer)numbers.get(“two”); System.out.println(“two = ” + n); 키의 대상은 산열 함수를 계산하여 그에 대응하는value의 위치를 확정하기 때문에 키의 대상은 모두hashCode와 equals 방법을 실현해야 한다.hashCode와 equals 방법은 루트 클래스 Object에서 계승됩니다. 사용자 정의 클래스를 키로 사용하면 조심스럽습니다. 산열 함수의 정의에 따라 두 대상이 같다면obj1입니다.equals(obj2) =true는 그들의hashCode는 반드시 같아야 하지만 만약에 두 대상이 다르다면 그들의hashCode는 반드시 다르지 않다. 만약에 두 대상의hashCode가 같다면 이런 현상을 충돌이라고 부른다. 충돌은 해시표를 조작하는 시간 지출을 증가시킬 수 있기 때문에 가능한 한 정의된hashCode() 방법은 해시표의 조작을 가속화시킬 수 있다.같은 대상에 다른hashCode가 있으면 해시표의 조작에 예상치 못한 결과가 나타날 수 있습니다. (기대하는 get 방법은null로 되돌아옴) 이런 문제를 피하려면 equals 방법과hashCode 방법을 동시에 복사하고 그 중 하나만 쓰지 마십시오.Hashtable은 동기화됩니다.HashMap 클래스인 HashMap은 Hashtable과 유사하지만 다른 점은 HashMap이 비동기적이고null, 즉nullvalue와nullkey를 허용하는 데 있다.그러나 HashMap을 Collection으로 간주할 때 (values () 방법은 Collection으로 되돌아갈 수 있으며, 그 교체 작업 시간 비용은 HashMap의 용량과 비례한다.따라서 교체 작업의 성능이 상당히 중요하다면,HashMap의 초기화 용량을 너무 높게 설정하거나loadfactor가 너무 낮게 설정하지 마십시오.WeakHashMap 클래스인 WeakHashMap은 개선된 HashMap으로 키에 대해 약한 인용을 실행합니다. 만약 키가 외부에서 인용되지 않는다면 이 키는 GC에서 회수될 수 있습니다.요약 창고, 대기열 등 작업과 관련된다면 List를 고려해야 하고, 빠른 삽입, 삭제가 필요한 경우 LinkedList를 사용해야 하며, 빠른 랜덤 접근이 필요한 경우 ArrayList를 사용해야 한다.만약에 프로그램이 단일 스레드 환경에서나 방문이 한 스레드에서만 진행된다면 비동기적인 클래스를 고려하면 효율이 비교적 높고 여러 스레드가 한 클래스를 동시에 조작할 수 있다면 동기화된 클래스를 사용해야 한다.해시표에 대한 조작에 특히 주의해야 하며, 키의 대상으로서 equals와hashCode 방법을 정확하게 복사해야 한다.가능한 한 인터페이스를 실제 형식이 아니라 되돌려줍니다. 예를 들어 Array List가 아닌 List를 되돌려줍니다. 그러면 나중에 Array List를 Linked List로 바꿔야 할 때 클라이언트 코드를 바꿀 필요가 없습니다.이것이 바로 추상적인 프로그래밍에 대한 것이다.

좋은 웹페이지 즐겨찾기