내가 살아가는 방식...

karma01.egloos.com

포토로그



Comparator, Comparable JAVA

Comparator와 Comparable는 모두 인터페이스로 객체들을 정렬 또는 이진검색트리를 구성하는데 필요한 메서드를 정의하고 있습니다.

Comparable를 구성하고 있는 클래스들은 같은 타입의 인스턴스끼리 서로 비교할 수 있는 클래스들, 주로 Integer와 같은 Wrapper클래스(Boolean제외)와 String, Date, File과 같은 것들이며 기본적으로 오름차순, 즉 작은 값에서부터 큰 값의 순으로 정렬되도록 구현되어 있습니다.

그래서 Comparable을 구현한 클래스는 정렬이 가능하다는 것을 의미합니다.

Comparable을 구현한 클래스들이 기본적으로 오름차순으로 정렬되어 있지만, 내림차순으로 정렬한다던가 아니면 다른 기준에 의해서 정렬되도록 하고 싶을때 Comparator를 구현해서 정렬기준을 제공 할 수 있습니다.

그럼 아래 구현한 예제를 보도록 합시다.


Hashset, LinkedHashSet, TreeSet JAVA

HashSet은 Set인터페이스를 구현한 가장 대표적인 컬렉션이며, Set 인터페이스의 특징대로 HashSet은 중복된 요소를 저장하지 않습니다.

HashSet에 새로운 요소를 추가할 때는 add메서드나 addAll메서드를 사용하는데, 만일 HashSet에 이미 저장되어 있는 요소와 중복된 요소를 추가하고자 한다면 이 메서드들은 false를 반환함으로써 중복된 요소이기 때문에 추가에 실패했다는 것을 알려줍니다.

HashSet은 저장순서를 유지하지 않으므로 저장순서를 유지하고자 한다면 LinkedHashSet을 사용해야합니다.

아래 HashSet의 예제를 보도록 합시다.

그럼 저장순서를 유지하는 LinkedHashSet의 예제를 아래에서 함 보도록 하겠습니다.

TreeSet은 이진검색트리(binary search tree)라는 자료구조의 형태로 데이터를 저장하는 컬렉션 클래스입니다.

이진검색트리는 정렬, 검색, 범위검색(range search)에 뛰어난 성능을 보이는 자료구조이며 TreeSet은 이진검색트리의 성능을 향상시킨 레드-블랙 트리(Red-Black tree)로 구현되어 있습니다.

그리고 Set인터페이스를 구현했으므로 중복된 데이터의 저장을 허용하지 않으며 정렬된 위치에 저장하므로 저장순서를 유지하지도 않습니다.

이진트리(binary tree)는 링크드리스트처럼 여러 개의 노드가 서로 연결된 구조로, 각 노드에 최대 2개의 노드를 연결 할 수 있으며 루트(root)라고 불리는 하나의 노드에서 부터 시작해서 계속 확장해 나갈 수 있습니다.

위 아래로 연결된 두 노드를 부모-자식관계에 있다고 하며 위의 노드를 부모노드, 아래의 노드를 자식노드라고 합니다. 부모-자식관계는 상대적인 것이며 하나의 부모노드는 최대 두 개의 자식노드와 연결될 수 있습니다.

class TreeNode {

TreeNode left; // 왼쪽 자식노드

Object element; // 객체를 저장하기 위한 참조변수

TreeNode right; // 오른쪽 자식노드

}

이진검색트리는 검색과 정렬에 유리하지만 노드의 추가 삭제에 시간이 걸리는 단점이 있습니다.

그럼 아래의 TreeSet의 예제를 보겠습니다.


Iterator, Enumeration, ListIterator에 대해서... JAVA

Iterator, Enumeration, ListIterator는 컬렉션 프레임워크에 저장된 요소들을 access하는데 사용되어지는 interface입니다.

Enumeration은 Iterator의 이전 인터페이스라고 보시면 되고, ListIterator는 Iterator의 발전된 인터페이스라고 보시면 됩니다.

그럼 먼저 Iterator부터 알아보도록 하겠습니다.

* Iterator

- 컬렉션 프레임워크에서는 컬렉션에 저장된 요소들을 읽어오는 방법을 표준화하였습니다. 컬렉션에 저장된 각 요소에 접근하는 기능을 가진 Iterator인터페이스를 정의하고, Collection인터페이스는 Iterator(Iterator를 구현한 클래스의 인스턴스)를 반환하는 iterator()를 정의하고 있습니다.

iterator()는 Collection인터페이스에 정의된 메서드이므로 Collection인터페이스의 자손인 List와 Set에도 포함되어 있습니다. 그래서 List나 Set인터페이스를 구현하는 컬렉션은 iterator()가 각 컬렉션의 특징에 알맞게 작성되어 있습니다. 컬렉션 클래스에 대해 iterator()를 호출하여 Iterator를 얻은 다음 반복문을 사용해서 컬렉션클래스의 요소들을 읽어 올 수 있습니다.

Iterator를 이용해서 컬렉션의 요소를 읽어오는 방법을 표준화했기 때문에 이처럼 코드의 재사용성을 높이는 것이 가능한 것입니다.

이처럼 공통 인터페이스를 정의해서 표준을 정의하고 구현하여 표준을 따르도록 함으로써 코드의 일관성을 유지하여 재사용성을 극대화하는 것이 객체지향 프로그래밍의 중요한 목적 중의 하나입니다.

Map인터페이스를 구현한 컬렉션 클래스는 키(key)와 값(value)을 쌍으로 저장하고 있기 때문에 iterator()를 직접 호출할 수 없고, 그 대신 keySet()이나 entrySet()과 같은 메서드를 통해서 키와 값을 각각 따로 Set의 형태로 얻어 온 후에 다시 iterator()를 호출해야 Iterator를 얻을 수 있습니다.

아래 예제 코드를 보도록 하겠습니다.

List클래스들은 저장순서를 유지하기 때문에 Iterator를 이용해서 읽어 온 결과 역시 저장 순서와 동일하지만 Set클래스들은 각 요소간의 순서가 유지 되지 않기 때문에 Iterator를 이용해서 저장된 요소들을 읽어 와도 처음에 저장된 순서와 같지 않습니다.

* Enumeration

Enumeration은 컬렉션 프레임웍이 만들어지기 이전에 사용된 것으로 Iterator의 구버젼이라고 생각하면 됩니다. 그래서 웬만하면 Enumeration보다 Iterator를 사용하시는게 나을듯합니다.

* ListIterator

ListIterator는 Iterator를 상속받아서 기능을 추가한 것으로, 컬렉션의 요소에 접근할 때 Iterator는 단방향으로만 이동할 수 있는 데 반해 ListIterator는 양방향으로의 이동이 가능합니다. 다만 ArrayList나 LinkedList와 같이 List인터페이스를 구현한 컬렉션에서만 사용할 수 있습니다.

아래는 ListIterator의 예제입니다.


자바 collection framework( stack, queue ) JAVA

스택(stack)은 마지막에 저장한 데이터를 가장 먼저 꺼내게 되는 LIFO(Last In First Out)구조로 되어 있고, 큐(queue)는 처음에 저장한 데이터를 가장 먼저 꺼내게 되는 FIFO(First In First Out)구조로 되어 있습니다.

쉽게 이야기하자면 만약 스택에 1,2,3이 넣는다면 꺼낼때는 3,2,1순서이고, 큐에 1,2,3을 넣는다면 1,2,3으로 꺼내게 된다.

아래는 스택의 예제입니다.


그리고 아래는 큐의 예제입니다.






















1 2 3 4 5 6 7 8 9 10 다음