2012년 11월 2일 금요일

자바의 트리셋(TreeSet)


java.util 패키지에 있는 트리셋(TreeSet)에 대해서 공부할텐데 강이의 자바강좌를 저번 시간에 들은 이들은 예고를 살짝(?) 했으니 아마도 오늘 내용에 대해서 벌써 알고 있을 것이라 생각한다. 그렇다! 요소들을 숫자든 문자든 자연적인 순서의 오름차순으로 정렬하는 것인데 그럴때 이용하는 클래스가 바로 트리셋이다.


오늘 예제는 재탕(?)을 하였다. 저번 예제를 그냥 트리셋으로만 바꿔서 어떻게 결과가 달라지는지 아주 단순히 비교할수 있도록 하였다. 여러분이 이전 강좌를 기억하리라 기대 아닌 기대(?)를 하면서 예제와 그에 따른 결과를 보도록 하자.^^


TreeSet={2,1,2,100,9,86}
ts size( ): 5
=== 강이의 JAVA강좌 ===
ts Number: 1
ts Number: 2
ts Number: 9
ts Number: 86
ts Number: 100

TreeSet2={A,B,C,A,E,D}
ts2 size( ): 5
=== 강이의 자바강좌 ===
ts2 Alphabet: A
ts2 Alphabet: B
ts2 Alphabet: C
ts2 Alphabet: D
ts2 Alphabet: E

예제 샘플은 저번이랑 똑같다. 결과에서 보다시피 트리셋 클래스도 해쉬셋처럼 중복은 허용하지 않는다. 하지만 트리셋 클래스를 이용하면 이렇게 쉽게 자연적인 순서대로의 정렬이 가능하다. 그런데 예제를 보면 필자가 HashSet을 TreeSet으로 바꾼거 이외에는 없는데 저번 예제의 해쉬셋을 건드리지 않고 그냥 해쉬셋 요소들을 트리셋에 넣을순 없을까...? 이렇게 속(?)으로 생각하고 있었다면 정말 자앙(?)하다. 잠시 라면이라도 끓여먹고 와라~ ㅎㅎ

해당 컬렉션내의 모든 요소들을 트리세트(크리쑤마쑤 트리아님.ㅎㅎ)에 넣을수 있는데 이럴때 이용하는 것이 Set 인터페이스에서 받아 구현한 addAll( )이라는 메소드이다. 예제를 기준으로 해쉬셋 요소들을 트리셋으로 옮기려면 숫자의 경우 ts.addAll(hs)를 쓰면 되고 문자의 경우 ts2.addAll(hs2)를 쓰면 된다.^^

해쉬셋을 이미 통달(?)한 여러분이기에 쉽게 기억하라는 뜻에서 예제를 저번과 같게 하였으니 오늘 내용이 머리속에 제대로 박혔으리라 기대한다.ㅎㅎ 필자가 예제에 직접 실행해보지 않은 부분에 대해서는 관련 요소들을 트리셋으로 옮겨가면서 여러분이 직접 소스를 만들어서 해보기 바란다.ㅎㅎ

그럼 여기서 한단계 더 나아가서 생각해 보기로 하겠다. 자연적인 순서(natural ordering)는 TreeSet에서 이렇게 바로 구할수 있겠지만 아예 반대로.. 거꾸로 음.. 그래 역순으로 정렬할순 없을까라는 의구심(?)이 들것이다. 이런 요소셋을 그냥 역순으로 정렬하는거 정도는 이제 손쉽게 가능해졌지만 아직까지 모르는 이들이 많을 것이다.ㅎㅎ 그것은 자바 6부터 새로나온 부분이기 때문에 관심있게 다시 보지 않았으면 아직까지 생노가다(?) 작업을 하고 있을텐데 오늘 강이의 자바강좌를 통해 이런 노역(?)에서 해방되기를 바라면서 계속해 보겠다.^^


이제부터는 자바6에서 등장한 신기술(?)을 살펴보도록 하겠다. 자바 6에서는 NavigableSet 인터페이스가 위처럼 추가되었는데 알아두면 관련 요소들을 다루는데 많은 도움이 될것이니 한번 살펴보기 바란다. 여기서는 그 중에서도 몇가지만 압축해서 예제를 선보이도록 하겠다. 빠른 이해를 위해 기존 예제를 토대로 새로운 기능을 실험하여 어려운건 없을테니 긴장풀고 편안하게 아래의 예제를 보기 바란다.ㅎㅎ


내용이 길어보이지만 절반은 기존 예제이므로 아래의 절반만 이해하면 되니 잠시 걱정은 접어두기 바라고 결과를 보면서 해설을 따라오기 바란다.^^

TreeSet={2,1,2,100,9,86}
ts size( ): 5
=== 강이의 JAVA강좌 ===
ts Number: 1
ts Number: 2
ts Number: 9
ts Number: 86
ts Number: 100
내림차순 반복자를 이용해서 거꾸로 출력
ts Number: 100
ts Number: 86
ts Number: 9
ts Number: 2
ts Number: 1
요소세트 자체를 그냥 거꾸로 출력
원본: [1, 2, 9, 86, 100]
결과: [100, 86, 9, 2, 1]
=== http://alecture.blogspot.com ===
[1, 2, 9, 86, 100]의 원본 ts에서 원하는 요소 찾기
ts.ceiling(86): 86
ts.floor(9): 9
ts.higher(86): 100
ts.lower(9): 2
ts.first( ): 1
ts.last( ): 100
=== 강이의 JAVA강좌 ===
[100, 86, 9, 2, 1]의 결과 ns에서 원하는 요소 찾기
ns.ceiling(86): 86
ns.floor(9): 9
ns.higher(86): 9
ns.lower(9): 86
ns.first( ): 100
ns.last( ): 1

여기서 우리가 보기 시작해야될 부분은 "내림차순 반복자를 이용해서 거꾸로 출력"한 곳이다. 말그대로 iterator를 통해서 출력하는데 이번엔 숫자가 역순으로 찍히는걸 볼수 있을 것이다. 이게 단 하나의 메소드만 바꿔주면 끝난다. 예제처럼 기존에 쓰던 iterator( ) 대신에 descendingIterator( ) 메소드만 넘겨주면 다른건 터치할 필요도 없이 원터치로 끝나버린다. 기가막히지 않는가? 거기다가 이것도 귀찮다 싶으면 아까전에 언급한 NavigableSet을 통해 관련셋을 바로 역순으로 정렬할수도 있다. 해당명령은 아래와 같다.
NavigableSet ns = ts.descendingSet( );


예제를 직접 실행하면서 보면 바로 이해가 갈것이다. 그밖에도 새로 추가된 ceiling, floor등의 메소드들이 있어서 어떤 것인지도 보여줄겸 살짝 예제에 추가시켜보았다. first나 last 메소드는 세트에서 가장 첫번째 요소나 마지막 요소를 찾을때 쓰는 메소드인데 이건 새로운건 아니지만 종종 쓰이니 그것도 하는김에 넣어보았다.ㅎㅎ

원하는 요소찾기에서 보면 ts랑 ns의 결과값들이 다른걸 볼수 있는데 그 차이는 어떤 세트가 기준 세트로 작동했는지에 따라서 동작이 달라지는데 그 의미를 되새겨보라고 만들어 놓은 것이다. ts는 정순이고 ns는 역순인데 그 기준 세트에 따라서 결과값이 달라지니 관심있게 살펴보기 바란다. 예제에 있는 메소드 기능들을 간략하게 설명하면 다음과 같다.

ceiling 메소드나 floor 메소드는 세트에 넣어준 값과 같은 값이 있을시 그 해당값을 리턴한다. 허나 higher 메소드나 lower 메소드는 말그대로 -er이 붙었으니 같은 값은 무시하고 그 다음에 관련된 해당값을 리턴한다. 물론 모두다 관련값이 없을시엔 null을 리턴한다. 쉽게 생각하는 방법은 세트에 넣어준 값의 위치를 기준으로 위(ceiling/higher)인지 아래(floor/lower)인지 판단하면 된다. 예를 들어 메소드에 5를 넣어준다고 가정하면 ts 세트일 경우 숫자 2 뒤에 들어간다 생각해야되고 ns 세트일 경우 역순이니까 숫자 2 앞에 들어간다 생각하고 답을 유추하면 된다. 그러면 ts 세트의 경우 9와 2가 나올것이고 ns 세트의 경우 2와 9가 나올것이다.ㅎㅎ 조금 헤깔릴지 모르겠지만 숫자 바꿔가면서 놀다보면 감이 잡힐 것이다. 이 정도만 알고 있으면 이해하는데 큰 문제는 없으리라 본다.^^

이로서 TreeSet을 공부해보는 시간을 가져보았다. 예제로 응용해 보고 싶은 부분들이 지금쯤 계속해서 생겨나고 있을것이라 생각한다. 그 욕망들(?)을 억누르지 말고 그대로 여러분의 자바머신에서 마음껏 뿜어내기 바라면서 오늘은 이만 마치겠다.^^

댓글 2개:

  1. What's up, I wish for to subscribe for this weblog to get most recent updates, therefore where can i do it please assist.

    Also visit my blog post ... Inexpensive treatment options of gynecomastia

    답글삭제