2021-01-05
오늘은 Set 컬렉션 중 HashSet에 대하여 알아보도록 하자. 우선 Set의 특성은 중복된 타입의 객체는 저장되지 않는다는 점이며, HashSet 역시 이와 같은 특징을 가지고 있다. 어렵지 않은 내용이니 바로 코드로 구현을 해보자.
package hHashSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class main {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
//순서없이 저장되며, 중복된 값은 저장되지 않는다.
set.add("aaa");
set.add("bbb");
set.add("ccc");
set.add("ddd");
set.remove("ccc");
Iterator<String> it = set.iterator();
while(it.hasNext()) {
String str = it.next();
System.out.println(str);
}
}
}
[ Set< 제네릭 타입(자신이 넣고자 하는 타입) > set변수명 = new HashSet <>(); ] 로 선언을 해주면 된다. 코드와 같이 add 메서드를 통해서 값을 추가할 수 있으며, remove메서드를 통해 원하는 객체를 제거할 수 있다.
Set은 인덱스를 검색해서 가져오는 메서드가 없어 Iterator와 Stream등을 통해 전체 객체를 반복해서 출력할 수 있다. 출력된 내용을 확인해보면, 중복된 객체 "aaa"는 하나만 저장되어 있으며, 제거된 "ccc"는 출력되지 않는 것을 확인할 수 있다.
이제 임이의 클래스를 가지는 HashSet 사용법을 알아보자 우선 사용할 클래스 People은 아래와 같다.
package hHashSet;
public class People {
private String name;
private int age;
public People(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof People) {
People human = (People) obj;
return human.name.equals(name) && human.age == age;
}else {
return false;
}
}
@Override
public int hashCode() {
return name.hashCode() + age;
}
}
이름과 나이를 필드로 가지면 모두 Getter와 Setter로 접근이 가능하도록 해주었다. 또한 각 필드 값 비교를 위해 equals와 hashCode 값을 재정의 해주었다. 다음 아래는 실행 클래스이다.
package hHashSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.stream.Stream;
public class main {
public static void main(String[] args) {
Set<People> pSet = new HashSet<>();
pSet.add(new People("aaa", 25));
pSet.add(new People("bbb", 35));
pSet.add(new People("ccc", 25));
pSet.add(new People("aaa", 25));
Iterator<People> itp = pSet.iterator();
while(itp.hasNext()) {
People p =itp.next();
//Iterator객체를 하나씩 받는 People의 p 변수 선언
System.out.println(p.getName()+ " " + p.getAge());
//p변수를 통해 name 과 age를 출력
}
System.out.println("________________________");
Stream<People> sSet = pSet.stream();
//pSet의 스트림 변수 sSet 선언
sSet.forEach(p -> System.out.println(p.getName() + " " + p.getAge()));
//forEach를 통해 모든 객체를 하나씩 돌면서 name과 age를 출력한다.
}
}
사실 사용법은 크게 다르지 않다. 제네릭 타입에 People을 선언해주고 이후 add메서드를 사용해 새로운 People 객체를 하나씩 넣어주면 된다. 다만 이번에는 객체의 출력을 Iterator / Stream 두 가지 모두를 이용해서 출력해 보았다. 사실 Stream을 사용할 줄 알면, Iterator는 사용할 일이 거의 없는데, 해당 내용을 방대하니 나중에 따로 정리하도록 하겠다.
이후 출력된 데이터 확인 결과 Iterator / Stream 모두 동일한 값을 도출하는 것을 확인할 수 있다.