컬렉션 프레임워크와 셋(Set)
37608 단어 해쉬셋자바트리comparatorcomparableJava
Set<E> 인터페이스를 구현하는 컬렉션 클래스들
대표적인 Set<E> 인터페이스를 구현하는 클래스
- HashSet<E>
- TreeSet<E>
Set<E> 인터페이스를 구현하는 클래스의 특성
- 중복 불가
- 순서 유지 불가
HashSet<E>
public static void main(String[]args){
Set<String> set = new HashSet<>();
set.add("Toy"); set.add("Box");
set.add("Robot"); set.add("Box"); // Box는 중복되므로 넣지않는다.
System.out.println("인스턴스 수 = " + set.size());
// 반복자를 이요한 전체 출력
for(Iterator<String> itr = set.iterator(); itr.hasNext();){
System.out.print(itr.next() + '\t');
}
// for-each문
for(String s : set){
System.out.print(s + '\t');
}
}
hashCode()와 equals()
equals
public boolean equals(Object obj)
- Object 클래스의 equals 메소드 호출 결과를 근거로 동일 인스턴스를 판단
hashCode
public int hashCode()
- set의 해쉬 코드를 반환
Set에서의 동일 인스턴스
- hashCode를 통해 동일한 해쉬 코드를 가진 집합에 대해 접근한다.
- 동일한 해쉬 코드를 가진 집합에 대해 equals 메소드를 통해 동일 인스턴스를 찾는다.
-> 더 빠른 탐색이 가능하다.
HashSet<E> 인스턴스에 저장할 클래스 정의의 예
class Num{
private int num;
public Num(int n){ num = n;}
@Override
public String toString(){return String.valueOf(num);}
// hashCode 오버라이딩
@Override
public int hashCode(){
return num % 3;
}
// equals 오버라이딩
@Override
public boolean equals(Object obj){
if(num == (Num)obj.num)
return true;
else
return false;
}
}
public static void main(String[]args){
Set<String> set = new HashSet<>();
set.add("Toy"); set.add("Box");
set.add("Robot"); set.add("Box"); // Box는 중복되므로 넣지않는다.
System.out.println("인스턴스 수 = " + set.size());
// 반복자를 이요한 전체 출력
for(Iterator<String> itr = set.iterator(); itr.hasNext();){
System.out.print(itr.next() + '\t');
}
// for-each문
for(String s : set){
System.out.print(s + '\t');
}
}
public boolean equals(Object obj)
public int hashCode()
-> 더 빠른 탐색이 가능하다.
class Num{
private int num;
public Num(int n){ num = n;}
@Override
public String toString(){return String.valueOf(num);}
// hashCode 오버라이딩
@Override
public int hashCode(){
return num % 3;
}
// equals 오버라이딩
@Override
public boolean equals(Object obj){
if(num == (Num)obj.num)
return true;
else
return false;
}
}
[코드 해석]
- Num 클래스는 hashCode() 메소드를 갖고 있기 때문에,
Num 클래스에 대해 Set을 생성할 때, 같은 해쉬 코드를 갖는 것들로 분류한다.
클래스에서의 적당한 hashCode() 메소드의 오버라이딩
1. 직접 만든다.
class Car{
private String model;
private String color;
...
@Override
public int hashCode(){
return (model.hashCode() + color.hashCode()) / 2;
}
}
- Car 클래스의 모든 데이터들에 대한 해쉬코드를 참고하여 hashCode() 메소드를 오버라이딩 했다.
2. java.util.Objects에 정의된 hash 메소드를 이용한다.
class Car{
private String model;
private String color;
...
@Override
public int hashCode(){
return Objects.hash(model, color);
}
}
TreeSet<E>
public static void main(String[]args){
TreeSet<Integer> tree = new TreeSet<Integer>();
tree.add(3); tree.add(1);
tree.add(2); tree.add(4);
System.out.println("인스턴스 수 = "+tree.size());
// for-each 문에 대한 반복
for(Integer n : tree){
System.out.print(n.toString() + '\t');
}
System.out.println();
// Iterator 반복자에 의한 반복
for(Iterator<Integer> itr = tree.iterator(); itr.hasNext();){
System.out.print(itr.next().toString() + '\t');
}
System.out.println();
}
- 반복자의 인스턴스 참조 순서는 '오름차순'을 기준으로 참조한다.
기준을 다르게 하려면 어떻게 해야할까? (Comparable 인터페이스)
- 제네릭 등장 이후로 Comparable 인터페이스가 바뀌었다.
interface comparable<T>
-> int compareTo(T o)
- TreeSet 인스턴스에 저장될 것을 고려한 클래스의 예
class Person implements Comparable<Person>{ private String name; private int age; // age를 기준으로 바꾸었다. @Override public int compareTo(Person p){ return this.age - p.age; } }
Comparator<T> ?
public TreeSet(Comparator<? super E> comparator)
-
이를 사용하여 기존에 정의되어있는 comparable의 기준을 바꿀 수 있다.
코드 1. Person 클래스의 정렬 기준을 바꾸다.
import java.util.Comparator;import java.util.TreeSet; // 1. 이미 compareTo가 정의되어 있는 상황이다. class Person implements Comparable<Person>{ private String name; private int age; // age를 기준으로 바꾸었다. @Override public int compareTo(Person p){ return this.age - p.age; } } // 2. Comparator을 구현하여 compare메소드를 정의하고 있다. // 기존의 Person의 기준을 바꾸었다. class PersonComparator implements Comparator<Person>{ public int compare(Person p1, Person p2){ return p2.age - p1.age } } public static void main(String[] args){ TreeSet<Person> tree = new TreeSet<>(new PersonComparator()); tree.add(new Person("Yoon", 37)); tree.add(new Person("HONG", 53)); tree.add(new Person("Park", 22)); for(Person p : tree) System.out.println(p); }
코드 2. Stirng 클래스의 정렬 기준을 바꾸다.
import java.util.Comparator; import java.util.TreeSet; // 문자열의 길이를 기준으로 정렬 class StringComparator implements Comparator{ public int compare(String s1, String s2){ return s1.length() - s2.length(); } } public static void main(String[] args){ TreeSet<String> tree = new TreeSet<>(new StringComparator()); tree.add("Box"); tree.add("Rabbit"); tree.add("Robot"); for(String s : tree) System.out.print(s.toString() + '\t'); System.out.println(); }
중복된 인스턴스를 삭제하는 방법 (ArrayList를 Set으로)
public static void main(String[]args){
List<String> lst = Arrays.asList("Box", "Toy", "Box", "Toy");
ArrayList<String> list = new ArrayList<>(lst);
// 중복이 있음을 확인
for(String s : list)
System.out.print(s.toString() + '\t');
System.out.println();
// 중복된 인스턴스를 거르기 (리스트를 셋으로)
HashSet<String> set = new HashSet<>(list);
// 셋을 다시 리스트로 변경
list = new ArrayList<>(set);
// 중복이 없어졌음을 확인
for(String s : list)
System.out.print(s.toString() + '\t');
System.out.println();
}
Author And Source
이 문제에 관하여(컬렉션 프레임워크와 셋(Set)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@songyw0517/컬렉션-프레임워크와-셋Set저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)