🔷 순서와 상관없이 중복을 허용하지 않는 경우에 사용한다.
🖥 테스트 코드
package hashset;
import java.util.HashSet;
public class HashSetTest {
public static void main(String[] args) {
HashSet<String> hashSet = new HashSet<>();
hashSet.add(new String("박영규"));
hashSet.add(new String("백준아"));
hashSet.add(new String("이도영"));
hashSet.add(new String("김청"));
hashSet.add(new String("박영규"));
System.out.println(hashSet);
}
}
🖨 출력
🔷 HashSet을 이용한 회원 관리 프로그램 구현
🖥 MemberHashSet.java
package hashset;
import java.util.*;
import collection.Member;
public class MemberHashSet {
private HashSet<Member> hashSet;
public MemberHashSet() {
hashSet = new HashSet<Member>();
}
// 회원 추가
public void addMember(Member member) {
hashSet.add(member);
}
// 회원 삭제
// Iterator를 활용한 순회를 이용
public boolean removeMember(int memberId) {
Iterator<Member> ir = hashSet.iterator();
while(ir.hasNext()) {
Member member = ir.next();
int tempId = member.getMemberId();
if(tempId == memberId) {
hashSet.remove(member);
return true;
}
}
System.out.println(memberId + "가 존재하지 않습니다.");
return false;
}
// 모든 회원 출력
public void showAllMember() {
for(Member member : hashSet) {
System.out.println(member);
}
System.out.println();
}
}
🖥 MemberHashSetTest.java
package hashset;
import collection.Member;
public class MemberHashSetTest {
public static void main(String[] args) {
MemberHashSet memberHashSet = new MemberHashSet();
Member memberLee = new Member(1, "이도영");
Member memberPark = new Member(2, "박영규");
Member memberKim = new Member(3, "김청");
Member memberBaek = new Member(4, "백준아");
memberHashSet.addMember(memberLee);
memberHashSet.addMember(memberPark);
memberHashSet.addMember(memberKim);
memberHashSet.addMember(memberBaek);
memberHashSet.showAllMember();
Member memberSpy = new Member(3, "김솔");
memberHashSet.addMember(memberSpy);
memberHashSet.showAllMember();
}
}
🖨 출력
⚠ 어라 뭔가 이상하다..?
🖥 Member.java
package collection;
public class Member {
private int memberId;
private String memberName;
public Member(int memberId, String memberName) {
this.memberId = memberId;
this.memberName = memberName;
}
public int getMemberId() {
return memberId;
}
public void setMemberId(int memberId) {
this.memberId = memberId;
}
public String getMemberName() {
return memberName;
}
public void setMemberName(String memberName) {
this.memberName = memberName;
}
@Override
public String toString() {
return memberName + " 회원님의 아이디는 " + memberId + "입니다.";
}
// hashCode()메서드가 회원 아이디를 반환 하도록 재정의
@Override
public int hashCode() {
return memberId;
}
// 매개변수로 받은 회원 아이디가 자신의 회원 아이디와 같다면 true 반환
@Override
public boolean equals(Object obj) {
if(obj instanceof Member) {
Member member = (Member)obj;
if(this.memberId==member.memberId) {
return true;
}
else {
return false;
}
}
return false;
}
}
🖨 이전 프로그램 재출력 결과
스파이는 equals()가 보내버렸으니 안심하라구 :)
💡 자바의 collection 인터페이스나 Map 인터페이스를 구현한 클래스 중 Tree로 시작하는 클래스는 데이터를 추가한 후 결과를 출력하면 결과 값이 정렬된다.
기억하지 못하는 그대를 위하여
자바스크립트로 알아보는 자료구조 (트리)
🖥 TreeSet 테스트 코드
package treeset;
import java.util.*;
public class TreeSetTest {
public static void main(String[] args) {
TreeSet<String>treeSet = new TreeSet<String>();
treeSet.add("박영규");
treeSet.add("백준아");
treeSet.add("이도영");
treeSet.add("김청");
for(String str : treeSet) {
System.out.println(str);
}
}
}
🖨 출력
한글 순으로 정렬되어 출력되는 것을 볼 수 있다.
🔷 TreeSet을 이용한 회원 관리 프로그램 구현
🖥 MemberTreeSet.java
package treeset;
import java.util.*;
import collection.Member;
public class MemberTreeSet {
private TreeSet<Member> treeSet;
public MemberTreeSet() {
treeSet = new TreeSet<Member>();
}
public void addMember(Member member) {
treeSet.add(member);
}
public boolean removeMember(int memberId) {
Iterator <Member>ir = treeSet.iterator();
while(ir.hasNext()) {
Member member = ir.next();
int tempId = member.getMemberId();
if(tempId == memberId) {
return true;
}
else {
return false;
}
}
return false;
}
public void showAllMember() {
for(Member member : treeSet) {
System.out.println(member);
}
System.out.println();
}
}
🖥 MemberTreeSetTest.java
package treeset;
import collection.Member;
public class MemberTreeSetTest {
public static void main(String[] args) {
MemberTreeSet memberTreeSet = new MemberTreeSet();
Member memberLee = new Member(1, "이도영");
Member memberPark = new Member(2, "박영규");
Member memberKim = new Member(3, "김청");
Member memberBaek = new Member(4, "백준아");
memberTreeSet.addMember(memberLee);
memberTreeSet.addMember(memberPark);
memberTreeSet.addMember(memberKim);
memberTreeSet.addMember(memberBaek);
memberTreeSet.showAllMember();
Member memberSpy = new Member(2, "김청");
memberTreeSet.addMember(memberSpy);
memberTreeSet.showAllMember();
}
}
⚠ 다만 그대로 구현했을 때 난데없이 이런 오류가 발생한다.
💡 Comparable 인터페이스
자기 자신과 전달받은 매개변수를 비교하는 인터페이스로 compareTo() 추상메서드를 포함하고 있다.
🖥 Comparable을 추가 구현한 Member.java
package collection;
public class Member implements Comparable <Member> {
private int memberId;
private String memberName;
public Member (int memberId, String memberName) {
this.memberId = memberId;
this.memberName = memberName;
}
public int getMemberId() {
return memberId;
}
public void setMemberId(int memberId) {
this.memberId = memberId;
}
public String getMemberName() {
return memberName;
}
public void setMemberName(String memberName) {
this.memberName = memberName;
}
@Override
public String toString() {
return memberName + " 회원님의 아이디는 " + memberId + "입니다.";
}
// hashCode()메서드가 회원 아이디를 반환 하도록 재정의
@Override
public int hashCode() {
return memberId;
}
// 매개변수로 받은 회원 아이디가 자신의 회원 아이디와 같다면 true 반환
@Override
public boolean equals(Object obj) {
if(obj instanceof Member) {
Member member = (Member)obj;
if(this.memberId==member.memberId) {
return true;
}
else {
return false;
}
}
return false;
}
// 메서드 재정의를 통해 추가한 회원 이름과 매개변수로 받은 회원 이름을 비교함
// -1을 곱하느냐 아니냐에 따라 오름차순과 내림차순 정렬이 결정되고, 아이디도 얼마든지 가능하다.
@Override
public int compareTo(Member member) {
return ((this.memberName.charAt(0) - member.memberName.charAt(0)) *(-1));
}
}
🖨 출력
다른 아이디지만 이름이 같은 김청이 들어오지 못한 모습이다.
🔷 Comparator 인터페이스
🤔 그럼 이 친구는 언제 쓰는건가요?
- 만약 어떤 클래스가 이미 Comparable 인터페이스를 구현했을 때 사용할 수 있다. 예를 들어 String 클래스는 이미 Comparable 인터페이스를 구현하고 있는데다가 final로 선언되어 있어서 compareTo() 메서드를 재정의할 수 없다. 이러한 경우에 Comparator를 사용한다.
🖥 ComparatorTest.java
package treeset;
import java.util.*;
class MyCompare implements Comparator<String> {
@Override
public int compare(String s1, String s2) {
return (s1.compareTo(s2)) /** -1*/;
}
}
public class ComparatorTest {
public static void main(String[] args) {
// 생성자에 Comparator를 구현한 객체를 매개변수로 전달한다.
Set<String> set = new TreeSet<String>(new MyCompare());
set.add("꽃가루를 날려");
set.add("폭죽을 더 크게 터뜨려");
set.add("샴페인을 더 크게 터뜨려");
System.out.println(set);
}
}
🖨 출력
🔷 자료를 쌍(pair)으로 관리하는 데 필요한 메서드가 정의되어 있는 인터페이스
해시브라운만 떠올리는 당신을 위해
자바스크립트로 보는 자료구조 (해시테이블)
index = hash(key)
🔷 HashMap으로 구현한 회원 관리 프로그램
🖥 MemberHashMap.java
package collection.map;
import java.util.*;
import collection.Member;
public class MemberHashMap {
private HashMap<Integer, Member> hashMap;
public MemberHashMap() {
hashMap = new HashMap<Integer, Member>();
}
// 회원을 key-value 쌍으로 추가
public void addMember(Member member) {
hashMap.put(member.getMemberId(), member);
}
// 입력된 키 값이 존재하는 회원을 삭제
public boolean removeMember(int memberId) {
if(hashMap.containsKey(memberId)) {
hashMap.remove(memberId);
return true;
}
System.out.println(memberId + "가 존재하지 않습니다.");
return false;
}
// 전체 회원 출력
public void showAllMember() {
Iterator<Integer> ir = hashMap.keySet().iterator();
while(ir.hasNext()) {
int key = ir.next();
Member member = hashMap.get(key);
System.out.println(member);
}
System.out.println();
}
}
❗ 회원 아이디로 쓰인 Integer형은 이미 equals()와 hashcode()가 재정의 되어 있기 때문에 다시 재정의할 필요가 없다.
🖥 MemberHashMapTest.java
package collection.map;
import collection.Member;
public class MemberHashMapTest {
public static void main(String[] args) {
MemberHashMap memberHashMap = new MemberHashMap();
Member memberLee = new Member(1, "이도영");
Member memberPark = new Member(2, "박영규");
Member memberKim = new Member(3, "김청");
Member memberBaek = new Member(4, "백준아");
memberHashMap.addMember(memberLee);
memberHashMap.addMember(memberPark);
memberHashMap.addMember(memberKim);
memberHashMap.addMember(memberBaek);
memberHashMap.removeMember(1);
memberHashMap.showAllMember();
}
}
🖨 출력
회원 삭제까지 야무지게 돌아간다.
💡 HashTable 클래스 역시 존재한다. 이 클래스는 Vector 클래스와 마찬가지로 멀티스레드를 위한 동기화를 제공한다. 이 말은 멀티스레드 환경이 아니라면 HashMap을 사용하는 것을 권장한다는 뜻이다.
🔷 key 값으로 자료를 정렬할 수 있는 클래스
❗ 예제에서 key 값으로 쓰일 Integer형은 이미 Comparable 인터페이스가 구현되어 있어서 따로 구현할 필요가 없다.
🖥 MemberTreeMap.java
package collection.map.treemap;
import java.util.*;
import collection.Member;
public class MemberTreeMap {
private TreeMap<Integer, Member> treeMap;
public MemberTreeMap() {
treeMap = new TreeMap<Integer, Member>();
}
// 회원 추가
public void addMember(Member member) {
treeMap.put(member.getMemberId(), member);
}
// 회원 삭제
public boolean removeMember(int memberId) {
if(treeMap.containsKey(memberId)) {
treeMap.remove(memberId);
return true;
}
System.out.println(memberId + "가 존재하지 않습니다.");
return false;
}
// 전체 회원 보기
public void showAllMember() {
Iterator<Integer> ir = treeMap.keySet().iterator();
while(ir.hasNext()) {
int key = ir.next();
Member member = treeMap.get(key);
System.out.println(member);
}
System.out.println();
}
}
🖥 MemberTreeMapTest.java
package collection.map.treemap;
import collection.Member;
public class MemberTreeMapTest {
public static void main(String[] args) {
MemberTreeMap memberTreeMap = new MemberTreeMap();
Member memberLee = new Member(1, "이도영");
Member memberPark = new Member(2, "박영규");
Member memberKim = new Member(3, "김청");
Member memberBaek = new Member(4, "백준아");
memberTreeMap.addMember(memberLee);
memberTreeMap.addMember(memberPark);
memberTreeMap.addMember(memberKim);
memberTreeMap.addMember(memberBaek);
memberTreeMap.showAllMember();
memberTreeMap.removeMember(2);
memberTreeMap.showAllMember();
}
}
🖨 출력
컬렉션 프레임워크에서 제공하는 여러 클래스를 살펴보았다.
유용하게 사용할 수 있길 기대한다.