참고

  • T06_HashSetTest.java
  • T07_TreeSetTest.java
  • T08_BasballTest.java
  • T09_EqualsHashcodeTest.java
  • T10_LottoTest.java

List와 Set의 차이점

List

  • 입력한 데이터의 순서가 있다.
  • 중복되는 데이터를 저장할 수 있다.

Set

  • 입력한 데이터의 순서가 없다.
  • 중복되는 데이터를 저장할 수 없다.

HashSet 의 CRUD

C: add

데이터 추가

Set hs1 = new HashSet();

hs1.add("DD");
hs1.add("AA");
hs1.add(3);
hs1.add(1);// 기본형타입으로 넣어도 자동컴파일 되지만, 되도록이면 객체화하자
hs1.add(new Integer(2));
hs1.add("CC");
hs1.add("BB");

// Set 데이터 : [DD, AA, CC, BB, 1, 2, 3]

중복을 허용하지 않는 데이터 추가

  • Set은 데이터의 순서가 없고, 중복을 허용하지 않는다.
  • 이미 있는 데이터를 add하면 false를 반환하고, 데이터는 추가되지 않음.
boolean isAdd = hs1.add("FF") // true
// Set 데이터 : [DD, AA, CC, BB, FF, 1, 2, 3]

// 중복 데이터를 추가할 시
isAdd = hs1.add("CC") // false
// Set 데이터 : [DD, AA, CC, BB, FF, 1, 2, 3]

U, D: clear, remove, add

  • Set의 데이터를 수정하려면 수정하는 명령이 따로 없기 때문에 해당 자료를 삭제한 후 새로운 데이터를 추가해주어야함.
    • List: list.set(index, 변경할 값) 이용
  • 삭제하는 메서드
    • 1) clear(): Set 데이터 전체 삭제
    • 2) remove(삭제할 자료): 해당 자료 삭제
// 예) 'FF'를 'EE'로 수정하기

hs1.remove("FF"); // FF 자료 삭제
// 삭제 후 데이터 : [DD, AA, CC, BB, 1, 2, 3]

hs1.add("EE"); // EE 자료 추가
// Set 데이터 : [DD, AA, CC, BB, EE, 1, 2, 3]

// 예2) 전체 자료 삭제
hs1.clear();
// clear 후 Set 데이터 : []
// Set의 자료 개수 : 0

R: Iterator 사용

  • Set은 데이터의 순서가 없기 때문에 List처럼 인덱스로 데이터를 하나씩 불러올 수 없다.
  • 데이터를 하나씩 가져오기 위해서는 Iterator로 처리해야 한다.

1단계: Iterator 객체 생성

  • Iterator: 인터페이스, hasNext()와 next()를 추상메서드로 가지고 있음.
Iterator it = hs1.iterator(); //Set의 iterator() 메서드 호출

2단계: 데이터 개수만큼 반복하기

  • hasNext(): 포인터 다음 위치에 데이터가 있으면 true, 없으면 false를 반환
  • next(): 포인터를 다음 자료위치로 이동하고, 이동한 위치의 자료를 반환
while(it.hasNext()){ // 다음 자료가 있는지 검사
    System.out.println(it.next());
}
// hs1에 있는 자료들 전부 출력됨

List를 활용한 HashSet 출력 예시

1. 1~100 사이의 '중복되지 않는' 정수 5개 만들기

  • 중복되지않는 = Set
Set<Integer> intRnd = new HashSet<>();

while(intRnd.size() < 5){ // Set의 데이터가 5개가 될 때까지
    int num = (int) (Math.random() * 100 + 1);
    intRnd.add(num);
}

// 만들어진 난수들 : [97, 99, 85, 54, 40]

2. List 활용해 출력하기

  • Collection 유형의 객체들은 서로 다른 자료 구조로 쉽게 변경해서 사용할 수 있다.
  • 다른 종류의 객체를 생성할 때 생성자에 변경할 데이터를 넣어주면 된다.
List<Integer> intRndList = new ArrayList<>(intRnd);

// 방법 1 : 일반 for문
for(int i=0; i < intRndList.size() ; i++){
    System.out.print(intRndList.get(i) + " ");
}
// 출력 결과 : 97 99 85 54 40 

// 방법 2 : 향상된 for문 (for each)
for(Integer number : intRndList){
    System.out.print(num + " ");
}
// 출력 결과 : 97 99 85 54 40 

TreeSet

  • TreeSet: 자동정렬 기능 있음 (=add시키는 순간 자동정렬) -> 검색속도 빠름 (이진트리)
  • HashSet: 데이터에 순서가 없음 (=등록되는 순서를 알지 못 함)

TreeSet의 자동정렬

TreeSet<String> ts = new TreeSet<>();

여기서 잠깐!

  • Set<String> ts = new TreeSet<>();이 아닐까?
    • 지금 이 예제에서는 TreeSet의 기능을 쓰려고 하는 것인데, 조상 타입의 참조변수(Set)로 자손(TreeSet)의 인스턴스를 참조한다면, 생성된 TreeSet 인스턴스의 멤버 중에서 Set클래스에 정의되지 않은 멤버들은 사용이 불가하기때문이다.
    • 초급자바책 p.152 다형성 참조
// 영어 대문자를 문자열로 변환하여 TreeSet에 저장하기
for(char ch = 'Z' ; ch >= 'A'; ch--){
    String temp = String.valueOf(ch);
    ts.add(temp);
}
// TreeSet 자료 : [A, B, C, ..., X, Y, Z]
// Z부터 넣었으나 TreeSet 특징인 add시 자동정렬으로 A-Z순으로 정렬됨

SortedSet

headSet()

  • TreeSet에 저장된 자료 중 '기준값'보다 작은 자료를 찾아서 SortedSet으로 반환
  • headSet(기준값): '기준값' 포함 X
  • headSet(기준값, 논리값): 논리값이 true이면 '기준값' 포함
SortedSet<String> ss1 = ts.headSet("K");
// K 이전 자료 : [A, B, C, D, E, F, G, H, I, J]

SortedSet<String> ss2 = ts.headSet("K", true); // 기준값 포함
// K 이전 자료(기준값 포함) : [A, B, C, D, E, F, G, H, I, J, K]

tailSet()

  • '기준값'보다 큰 자료를 찾아 SortedSet으로 반환
  • tailSet(기준값): '기준값' 포함
  • tailSet(기준값, 논리값): 논리값이 false면 '기준값' 제외
SortedSet<String> ss3 = ts.tailSet("K");
// K 이후 자료 : [K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z]
SortedSet<String> ss4 = ts.tailSet("K", false);
// K 이후 자료(기준값 미포함) : [L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z]

subSet()

  • subSet(기준값1, 기준값2): 기준값1 ~ 기준값2 사이의 값 (1포함, 2미포함)
  • subSet(기준값1, 논리값1, 기준값2, 논리값2): 각 기준값을 포함할 지 여부 설정, (논리값 true=포함)
SortedSet<String> ss5 = ts.subSet("K", "N");
// K(포함) ~ N(미포함) : [K, L, M]
SortedSet<String> ss6 = ts.subSet("K",true,"N",true);
// K(포함) ~ N(포함) : [K, L, M, N]
SortedSet<String> ss7 = ts.subSet("K",false,"N",false);
// K(미포함) ~ N(미포함) : [L, M]
SortedSet<String> ss8 = ts.subSet("K",false,"N",true);
// K(미포함) ~ N(포함) : [L, M, N]
profile
갈 길이 멀다

0개의 댓글