Dipa's document :: [JAVA] Collection - Set 컬렉션(HashSet, TreeSet)

이번시간은 Set 컬렉션에 대해서 다뤄보도록 하겠습니다.ㅎㅎ

Set 컬렉션은 앞서 List 컬렉션과는 다르게 index로 관리되어지는 것이 아니라서 저장순서가 유지되어 지지 않습니다. 마치 하나의 주머니안에 데이터(객체)를 담는거라고 생각하시면 좋을꺼 같습니다 ㅎ

Set 컬렉션의 특징은 앞서 소개한 바로 순서가 보장되지 않고, 중복 저장이 되지 않는 것이 특징입니다.

따라서 Set 인터페이스의 메소드들은 기존의 List 인터페이스를 구현한 메소드들 중에서 인덱스와 관련된것은 뺴고 모두 동일하다고 생각하시면 됩니다.

Set 인터페이스를 구현한 대표적인 클레스로는 HashSet, TreeSet이 있습니다. 먼저 이 포스팅에서는 HashSet에서만 다루겠습니다. TreeSet같은경우에는 다음 포스팅에 나올 TreeMap과 함꼐 다루도록 하겠습니다. 

* HashSet

HashSet클레스 같은경우는 객체를 순서없이 저장을하고, 동일한 객체는 저장을 하지 않는 부분에 있어서 Set 인터페이스를 구현한 클레스 입니다.

HashSet 클레스는 객체를 저장을 하기전에 먼저 HashCode()를 통해서 해시코드를 얻어내고, 그 해시코드의 값을 가지고 동일한 객체가 저장이 되어 있는지 없는지에 대해서 조사를 하게 됩니다. 만약 동일한 해쉬코드가 나오면 다시 equals()를 통해서 한번더 점검을 한 후, 저장을 할지 말지에 대한 결정을 하게 됩니다.

HashCode()와, equals()메소드의 부분은 제 블로그에 나와 있으니 한번 참고를 해보시면 좋을꺼 같네요^^

그렇다면, 순서도 없이 저장된 객체를 어떻게 꺼내서 처리를 할 수 있을까요? 

결론부터 말하면 Set 인터페이스의 iterator() 라는 메소드 즉 반복자를 통해서 이용을 할 수 있습니다.  그럼 Iterrator 인터페이스를 보도록 하겠습니다.


public interface Iterator<E> { /** * Returns {@code true} if the iteration has more elements. * (In other words, returns {@code true} if {@link #next} would * return an element rather than throwing an exception.) * * @return {@code true} if the iteration has more elements */ boolean hasNext(); /** * Returns the next element in the iteration. * * @return the next element in the iteration * @throws NoSuchElementException if the iteration has no more elements */ E next(); /** * Removes from the underlying collection the last element returned * by this iterator (optional operation). This method can be called * only once per call to {@link #next}. The behavior of an iterator * is unspecified if the underlying collection is modified while the * iteration is in progress in any way other than by calling this * method. * * @implSpec * The default implementation throws an instance of * {@link UnsupportedOperationException} and performs no other action. * * @throws UnsupportedOperationException if the {@code remove} * operation is not supported by this iterator * * @throws IllegalStateException if the {@code next} method has not * yet been called, or the {@code remove} method has already * been called after the last call to the {@code next} * method */ default void remove() { throw new UnsupportedOperationException("remove"); } /** * Performs the given action for each remaining element until all elements * have been processed or the action throws an exception. Actions are * performed in the order of iteration, if that order is specified. * Exceptions thrown by the action are relayed to the caller. * * @implSpec * <p>The default implementation behaves as if: * <pre>{@code * while (hasNext()) * action.accept(next()); * }</pre> * * @param action The action to be performed for each element * @throws NullPointerException if the specified action is null * @since 1.8 */ default void forEachRemaining(Consumer<? super E> action) { Objects.requireNonNull(action); while (hasNext()) action.accept(next()); } }

이제 Iterator를 통해서 HashSet 클레스의 객체를 처리해보도록 하겠습니다.


public class Member {
	private String name;
	private int age;
	
	public Member(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 int hashCode() {
		return name.hashCode() + age;
	}
	
	@Override
	public boolean equals(Object obj) {
		if(obj instanceof Member){
			Member member = (Member)obj;
			return (member.name.equals(this.name))&&(member.age==this.age);		
		}else{
			return false;
		}
	}
	
	@Override
	public String toString() {
		return name + " : " + age;
	}
}


public class HashSetExample {

	public static void main(String[] args) {
	
		Set<String> StringSet = new HashSet<String>();
		
		StringSet.add("지승훈");
		StringSet.add("홍길동");
		StringSet.add("지자바");
		StringSet.add("지후니");
			
		
		Iterator<String> iterator = StringSet.iterator();
		
		System.out.println("Set Size : " + StringSet.size());
		while(iterator.hasNext()){
			System.out.println(iterator.next().toString());
		}
		
		Set<Member> member = new HashSet<Member>();
		
		
		member.add(new Member("지승훈",27));
		member.add(new Member("홍길동",30));
		
		Iterator<Member> iterator2 = member.iterator();
		
		while(iterator2.hasNext()){
			System.out.println(iterator2.next().toString());
		}
	}

}


Posted by SH후니
,