JAVA
[JAVA] Set 인터페이스(HashSet, LinkedHashSet, TreeSet)
정공자씨
2024. 4. 25. 14:28
[ 컬렉션 프레임워크의 종류 ]
- Collcetion 인터페이스
- Map 인터페이스
[ collection 인터페이스 ]특징
- List, Set,Queue에서 상속하는 최상위 컬렉션 타입
- 업캐스팅으로 다양한 종류의 컬렉션 자료형을 받아서 자료를 삽입, 삭제, 조회할 수 있음
종류
- List
- Queue
- Set
Set 인터페이스
특징
- 객체의 중복을 허용하지 않음
- 순위(index)가 지정되지 않음
- 집합적인 특징을 가지고 있음
종류
1. HashSet 클래스
2. LinkedHashSet 클래스
3. TreeSet 클래스
HashSet 클래스
특징
- 객체의 중복 저장을 허용하지 않음
- 중복 저장이 불가능하므로, null값도 1개만 저장됨
- 순서(index)가 지정되지 않음
- 따라서, 요소를 가지고 오는 get(index) 메서드 없음
- 출력 시에 저장된 순서대로 출력되지 않음
장점
- 데이터의 추가, 삭제, 검색의 속도가 빠르고
- 임의 요소에 접근하는 속도가 빠름
동등한 객체인지를 확인하는 문법적 특징
- 문자열(리터럴, new로 문자열 생성), 기본 타입의 wrapper 클래스(Integer, Float 등)는 동일한 객체를 저장하면 중복 없이 1번만 저장됨
- new 연산자로 객체를 생성(사용자가 직접 만든 클래스의 객체 등)는 중복되서 저장됨
왜 new연산자로 생성한 객체의 중복 저장은 허용하는 걸까?
- 그 이유는 동등한 객체인지를 확인하기 위해서, 객체 생성시 할당되는 해시코드(hashcode)를 이용하여, hashcode()와 equal() 메서드로 동일한 객체인지를 판단하기 때문
- 프로그램 실행 시에 new 연산자로 객체를 생성하면, 각 객체는 생성된 메모리 위치를 기반으로 한 고유번호인 해시코드(HashCode)가 할당됨
- 따라서 두 객체의 HashCode() 메서드를 호출하여 두 객체의 해시코드가 같은 지를 비교하고
- true이면 equals() 메서드를 호출하고
- false이면 다른 객체로 판별 → HashSet에 저장
- equals() 메서드를 이용해서, 필드값(데이터의 값)을 비교함
- 각각 객체의 필드값(데이터의 값)이 같은지를 비교하여
- true이면 두 객체가 같다고 생각해서 HashSet에 저장하지 않고
- false이면 두 객체의 필드값이 다름 → HashSet에 저장
문법
1. HashSet의 객체 생성
Set set = new HashSet();
2. 객체의 저장
- HashSet에 문자열과 기본 타입의 wrapper 클래스의 객체 저장시, 중복 저장을 허용하지 않음
public class ArrayListTest2 {
public static void main(String[] args) {
Set set = new HashSet();
// 저장된 객체의 중복을 허용하지 않음
set.add("정공자");
set.add(Integer.valueOf(425));
set.add(Float.valueOf(4.25F));
set.add(Integer.valueOf(425));
set.add("정공자");
System.out.println(set); // [정공자, 4.25, 425], 중복값 저장X
// Iterator 객체로 순회
Iterator iter = set.iterator();
while (iter.hasNext()) { // hasNext(): 집합에 값이 남아있는지를 확인
System.out.println(iter.next()); // next(): 값을 가지고 옴
}
}
}
- new연산자로 생성한 객체는 HashSet에 중복 저장 허용
public class ArrayListTest3 {
public static void main(String[] args) {
Set set = new HashSet();
Coffee coffee1 = new Coffee("마끼아또", 4500);
set.add(coffee1);
set.add("정공자");
set.add(new String("비정공씨"));
set.add(Integer.valueOf(425));
set.add(Float.valueOf(4.25F));
set.add(Integer.valueOf(425));
set.add("정공자");
set.add(new String("비정공씨")); // 중복, 저장 불가
Coffee coffee2 = new Coffee("마끼아또", 4500);
set.add(coffee2); // coffee2와 해시코드 값이 다름, 저장
System.out.println(set);
// [Coffee[마끼아또, 4500], 정공자, 비정공씨, 4.25, 425, Coffee[마끼아또, 4500]]
System.out.println("---------------------------------------------------------")
// Iterator 객체로 순회
Iterator iter = set.iterator();
while (iter.hasNext()) { // hasNext(): 집합에 값이 남아있는지를 확인
System.out.println(iter.next()); // next(): 값을 가지고 옴
}
}
}
[ 실행 결과 ]
[ HashSet에 저장되는 객체]
1. 문자열과 기본 타입의 wrapper 클래스의 객체 저장시, 중복 저장을 허용하지 않음
2. new연산자로 생성한 객체는 HashSet에 중복 저장 허용
LinkedHashSet 클래스
특징
- 중복을 허용하지 않음(set의 특징)
- 순서를 가짐
- 추가된 순서대로 접근할 수 있음
- 가장 최근에 접근한 순서대로 접근할 수 있음
Hashset
- 순서를 가지지 않음
LinkedHashset
- 순서를 가짐
사용하는 예
- 중복을 제거하면서도, 저장한 순서를 유지하고 싶을 때 사용
예제
public class Test2 {
public static void main(String[] args) {
Set linkedHashSet = new LinkedHashSet();
linkedHashSet.add(3);
linkedHashSet.add(1);
linkedHashSet.add(7);
linkedHashSet.add(3); // 중복된 수 저장X
linkedHashSet.add(5);
System.out.println(linkedHashSet.size()); // 4, 중복 저장 X
System.out.println(linkedHashSet.toString()); //[3, 1, 7, 5], 순서대로 저장
}
}
[ 실행 결과 ]
TreeSet 클래스
특징
- 이진 검색 트리의 자료 구조 형태로 데이터가 저장
- 중복을 허용하지 않고
- 순서를 가지지 않음
- 대신 객체를 정렬하여 저장하고 있음
- 저장된 객체의 정렬 기능을 제공함
- 자동으로 오름차순으로 저장
Hashset
- 순서를 가지지 않음
LinkedHashset
- 순서를 가짐
TreeSet
- 객체를 정렬하여 저장(오름차순)
예제
public class Test1 {
public static void main(String[] args) {
Set treeSet = new TreeSet();
treeSet.add(5);
treeSet.add(3);
treeSet.add(8);
treeSet.add(1);
treeSet.add(10);
// iterator로 순회하여 출력
Iterator iter = treeSet.iterator();
while (iter.hasNext()) {
System.out.println(iter.next()); // [1,3,5,8,10], 오름차순 정렬하여 출력
}
// 향상된 for문으로 출력
for (Object tree : treeSet) {
System.out.print(tree); // [1,3,5,8,10], 오름차순 정렬하여 출력
}
}
}
[ 실행 결과 ]
출처