순서에 상관없이, 어떤 데이터가 존재하는지를 확인하기 위한 용도로 많이 사용된다. 중복되는 것을 방지하고, 원하는 값이 포함 되어 있는지를 확인하는것이 주 용도이다.
HashSet: 순서가 전혀 필요없는 데이터를 해시 테이블 hash table 에 저장한다. Set중에서 가장 성능이 좋다.
TreeSet: 저장된 데이터의 값에 따라서 정렬되는 셋이다. red-black 이라는 트리 tree타입으로 값이 저장되며, HashSet보다 약간 성능이 느리다.
LinkedHashSet:연결된 목록 타입으로 구현된 해시 테이블에 데이터를 저장한다. 저장된 순서에 따라서 값이 정렬된다. 대신 성능이 이 셋 중에서 가장 나쁘다.
HashSet
package com.example.test;
import java.util.HashSet;
import java.util.Iterator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SetTest {
public static void main(String[] args) {
SpringApplication.run(SetTest.class, args);
HashSet set = new HashSet();
set.add("달걀");
set.add("치즈");
set.add("치킨");
set.add("피자");
set.add("치즈");
Iterator it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
결과 화면을 확인하면 중복되는 Value인 치즈 1개를 제외하고 나머지 4개가 출력된것을 확인 할 수 있다.
확인해보면 HashSet은 순서가 상관없는 데이터를 hash table에 중복된 값을 제외해서 저장하는걸 알 수 있었다.
List<String> list = new ArrayList<String>(set);
Collections.sort(list);
Set을 정렬이가능하게 List로 변화시켜주고
Collections.sort()를 활용하면 정렬되지 않았던 hashSet도 정렬이 가능하다.
TreeSet
TreeSet은 이진검색트리(binary search tree)라는 자료구조의 형태로 데이터를 저장하는 컬렉션 클래스 이다. 이진 검색 트리는 정렬, 검색, 범위검색에 높은 성능을 보이는 구조로 TreeSet은 이진 검색트리의 성능을 향상 시킨 레드-블랙-트리로 구현되어있다.
또한 위의 Set인터페이스로 구현했기 때문에 중복된 데이터의 저장을 허용하지 않으며, 저장 순서또한 유지 하지 않는다. 값의 순서에따라 정렬해준다
package com.example.test;
import java.util.HashSet;
import java.util.Iterator;
import java.util.TreeSet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SetTest {
public static void main(String[] args) {
SpringApplication.run(SetTest.class, args);
TreeSet set = new TreeSet();
for(int i=15; i>0;i--) {
set.add(i);
}
set.add(-3);
set.add(-4);
set.add(15);
set.add(11);
Iterator it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
위의 사진을보면 -4~15까지 정렬되서 출력되는것을 확인 할 수있다.
여기서 위의 TreeSet을 HashSet으로 다시돌려보면
음수를 구분하지 못한채로 정렬되어있는것을 확인 할 수있다.
또한 subSet을 통한 탐색도 가능하다
System.out.println(set.subSet(1,5));
통해서 1부터 5미만의 수를 출력하거나 String Value값을 통해 원하는 단어가 포함된 값도 탐색이 가능하다.
Compareble 인터페이스로 구현하여 정렬하는법
package com.example.test;
class Student implements Comparable<Student> {
private String name;
private int point;
public Student(String name, int point) {
this.name = name;
this.point = point;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPoint() {
return point;
}
public void setPoint(int point) {
this.point = point;
}
@Override
public int compareTo(Student student) {
return this.point -student.point; //점수로 비교하기위함 오름차순 순 (내림차순은 반대)
}
@Override
public String toString() {
return " [name=" + name + ", point=" + point + "]";
}
}
Student클래스를 만들어 Comparable을 구현받아준다. Stduent클래스는 TreeSet이 삽입될때 오버라이딩된 compareTo 메소드를 이용하여 정렬을 진행한다.
package com.example.test;
import java.util.Iterator;
import java.util.TreeSet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SetTest {
public static void main(String[] args) {
SpringApplication.run(SetTest.class, args);
TreeSet<Student> set = new TreeSet<Student>();
set.add(new Student("A",100));
set.add(new Student("B",120));
set.add(new Student("C",130));
set.add(new Student("D",140));
set.add(new Student("E",110));
Iterator it = set.iterator();
while(it.hasNext()) {
System.out.print(it.next()+" ");
}
}
}
결과창을보면 point의 점수순으로 정렬된것을 확인 할 수있었다.
linkedhashset
linkedHashSet도 set인터페이스를 참조하므로 중복된 데이터를 저장할수없다. 또한 입력한 순서되로 저장이 되는 특징이있다.
package com.example.test;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.TreeSet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SetTest {
public static void main(String[] args) {
SpringApplication.run(SetTest.class, args);
LinkedHashSet<Student> set = new LinkedHashSet<Student>();
set.add(new Student("A",100));
set.add(new Student("C",130));
set.add(new Student("B",120));
set.add(new Student("D",140));
set.add(new Student("E",110));
Iterator it = set.iterator();
while(it.hasNext()) {
System.out.print(it.next()+" ");
}
}
}
위의 결과창을보면 A C B D E 가 순서대로 출력된것을 확인 할 수있었다.
sortedset
SortedSet은 컬렉션중 하나로 Collection이기도 하며 Set이기도 하다.
실제로 SortedSet은 Set을 상속한 인터페이스이다. 이 이유로 Set에서 할 수있는 모든 메소드 호출을 SortedSet에서도 사용이 가능하다.
또한 SortedSetd은 Set과 다른점이 있다면 Set은 객체의 순서를 상관하지 않고 객체의 중복여부에만 관심을 갖는데 반해 SortedSet은 객체의 중복여부뿐만 아니라 객체 끼리의 순서에도 관심을 갖고 있다.
물론 SortedSet에 있는 객체끼리의 순서가 있다고 해서 List처럼 지정한 위치에 객체를 넣을수 있는건 아니다. 객체의 순서에 관심이 있다는것은 iterator을 통해서 객체를 탐색할 때 적절한 순서에 따라 객체를 얻어내는 것이다.
List의 구현 클래스이므로 ArrayList나 Vector와 사용 방법은 동일하다. 하지만 구조는 다르게 구성되어있다. 위의 컬렉션들은 인덱스로 데이터를 관리하지만 LinkedList는 인접한 곳을 링크하여 체인처럼 관리한다. LinkedList는 중간의 데이터를 삭제할 때 인접한 곳의 링크만을 변경하면 되기 때문에 중간에 데이터를 추가/삭제하는 경우 처리 속도가 빠르다.
List<E> list = new LinkedList<E>();
상황에 따라 적절한 컬렉션을 사용하면 될거같다. 찾아보니 vector의경우 요즘 JAVA에서는 잘안쓰이는 추세라고한다...