2020년 10월 27일

업데이트:


List

LinkedList

List의 후손으로, 인접 참조를 링크해 체인처럼 관리한다. 특정 인덱스에서 객체를 제거하거나 추가하게 되면 바로 앞/뒤 링크만 변경하면 되기 때문에 객체 삭제와 삽입이 빈번하게 일어나는 곳에서는 ArrayList보다 성능이 좋다.

List<E> list = new LinkedList<E>();


Comparable, Comparator



Set

저장 순서가 유지되지 않고, 객체와 null을 중복해서 저장할 수 없다. Set 컬렉션에는 HashSet, LinkedHashSet, TreeSet 등이 있다.




HashSet

Set에 객체를 저장할 때 hash 함수를 사용하여 처리 속도가 빠르다. 동일 객체 뿐 아니라 동등 객체도 중복하여 저장하지 않는다.

Set<E> set = new HashSet<E>();


LinkedHashSet

HashSet과 거의 동일하지만 Set에 추가되는 순서를 유지한다는 점이 다르다.


Set 실습코드

// Student.java
public class Student implements Comparable<Student>{
					//Comparable : 객체의 기본 정렬 기준을 구현하는데 사용하는 인터페이스
	private String name;
	private int age;
	private int javaScore;
	
	public Student() {}
	
	public Student(String name, int age, int javaScore) {
		super();
		this.name = name;
		this.age = age;
		this.javaScore = javaScore;
	}

	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;
	}

	public int getJavaScore() {
		return javaScore;
	}

	public void setJavaScore(int javaScore) {
		this.javaScore = javaScore;
	}

	@Override
	public String toString() {
		return "Studnet [name=" + name + ", age=" + age + ", javaScore=" + javaScore + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + javaScore;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (age != other.age)
			return false;
		if (javaScore != other.javaScore)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

	@Override
	public int compareTo(Student o) {
		// 기본 정렬 기준
		// 이름 오름차순으로 정렬
		// 반환 값 음수, 0 현재 순서 유지, 양수일 때 바꿈
		
		return this.name.compareTo(o.name);
    }
}


package com.kh.collection.set.model.service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;

import javax.rmi.CORBA.Stub;

import com.kh.collection.set.model.vo.Student;
import com.kh.collection.set.model.vo.Student;

public class SetService {
	
	// Set(집합)
	// - 데이터의 순서가 존재하지 않음
	// - 중복 값을 허용하지 않음 (Null도 한 번만 저장할 수 있음)
	
	public void example1() {
		// HashSet
		// - 저장되는 객체를 hashCode()를 이용하여 동일 여부를 판단
		//   --> 동일한 객체가 저장될 경우 중복 제거 진행
		
		Set<String> set = new HashSet<String>();
		
		set.add("안녕하세요");
		set.add("안녕");
		set.add("반갑습니다");
		set.add("공부하세요!");
		
		// 순서 유지 X
		System.out.println(set.toString());
		
		// 중복 데이터 X -> 중복 제거
		set.add("안녕");
		set.add(null);
		set.add(null);
		set.add(null);
		
		System.out.println(set.toString());
		
	}
	
	
	
	public void example2() {
		// HashSet, Student 사용
		// Student로 타입이 제한된 set 객체를 참조하는 참조변수 set
		//Set<Studnet> set = new HashSet<>(); // 오른쪽 Student 생략 가능 --> 타입 추론
		Set<Student> set = new LinkedHashSet<Student>();
		//LinkedHashSet : 순서를 유지한다.
		
		// 참조변수에 선언된 제네릭을 통해 생성되는 객체의 제네릭을 추론함
		
		set.add(new Student("유현재", 27, 100));
		set.add(new Student("강수정", 27, 200));
		set.add(new Student("이한솔", 27, 300));
		
		// 중복 삽입
		set.add(new Student("유현재", 27, 100));
		// 중복 제거를 위해서는 Student에 equals(), hashcode()가 오버라이딩 되어있어야 함
		System.out.println(set);
		
		/* hashCode
		 * - 객체에 대한 서명 또는 checksum(중복 검사)
		 *   -> 객체를 서로 구분하는 용도의 정수
		 * 
		 */
		
		// size()
		System.out.println("set 크기 : " + set.size());
		
		// remove(Student std)
//		System.out.println("삭제 성공 : " + set.remove(new Studnet("이한솔", 27, 300)));
//		System.out.println(set);
		
		// set은 순서가 없기 때문에 원하는 데이터만을 꺼내보는 것이 불가능함
		//  -> 내부에 있는 모든 데이터를 무작위로 다 꺼내는 것은 가능함
		
		// 1. Set -> List로 변환
		List<Student> list = new ArrayList<Student>(set);
		
		// collection은 List와 Set의 공통점을 추출해서 만든 인터페이스 
		// collection Framework -> List, Set, Map이 포함됨
		System.out.println("Set - List로 변환");
		for(int i = 0; i < set.size(); i++) {
			System.out.println(list.get(i));
		}
		
		
		// 2. Iterator 반복자를 이용한 출력
		// 단점 : Iterator는 한 방향으로만 접근 가능함(단방향)
		// -> ListIterator(양방향)
		
		System.out.println("=========================================================");
		Iterator<Student> it = set.iterator();
		
		while(it.hasNext()) { 
			// hasNext() : 다음 반복 접근할 객체가 있을 경우 true / 없으면 false 반환
			System.out.println(it.next());
			// next() : 다음 객체를 얻어옴
			
		}
		
		// 3. 향상된 for문
		// 배열 또는 컬렉션 요소에 반복 접근하는 용도
		System.out.println("향상된 for문");
		for(Student std : set) {
			System.out.println(std);
		}
	}
	
	public void example3() {
		//TreeSet
		// - 검색 기능이 강화된 Set으로
		// 계층 구조를 활용한 이진트리 자료구조 형태의 Set
		
		// - 기본적인 Set의 특징 (순서 X, 중복 X) + 정렬
		Set<Integer> treeSet = new TreeSet<Integer>();
		
		treeSet.add(5);
		treeSet.add(15);
		treeSet.add(7);
		treeSet.add(3);
		treeSet.add(9);
		treeSet.add(8);
		System.out.println(treeSet);
	}
	
	
	public void example4() {
		// 로또 번호 생성기
		Set<Integer> lotto = new TreeSet<Integer>();
		
		while(lotto.size() < 7) {
			int random = (int)(Math.random() * 45 + 1);
			lotto.add(random);
		}
		
		System.out.println(lotto);
		
	}
	
	public void example5() {
		Set<Student> set = new TreeSet<Student>();
		
		set.add(new Student("홍길동", 29, 80));
		set.add(new Student("유관순", 28, 90));
		set.add(new Student("이이", 25, 85));
		set.add(new Student("도레미", 26, 100));
		set.add(new Student("세종", 32, 95));
		
		for(Student std : set) {
			System.out.println(std);
		}
	}
	
	
	public void example6() {
		// 숫자 7개를 입력받아
		// 생성된 로또 번호와 몇 개가 일치하는지 출력
		
		List<Integer> lotto = new ArrayList<Integer>();
		Set<Integer> comLotto = new TreeSet<Integer>();
		Scanner sc = new Scanner(System.in);
		int count = 0;
		System.out.print("숫자 7개 입력 : ");
		while(comLotto.size() < 7) {
			if(lotto.isEmpty()) {
				for(int i = 0; i < 7; i++) {
					int num = sc.nextInt();
					lotto.add(num);
				}
			}
			int random = (int)(Math.random() *45 +1);
			comLotto.add(random);
			List<Integer> list = new ArrayList<Integer>(comLotto);
		}
		System.out.println("생성된 로또 번호 : " + comLotto);
		System.out.print("일치하는 번호 : ");
		for(int i : comLotto) {
			for(int j = 0; j < lotto.size(); j++) {
				if(i == lotto.get(j)) {
					System.out.print(i + " ");
					count++;
				}
			}
		}
		System.out.println("\ncount : " + count);
      }	
	}
}



Map

키(Key)와 값(Valuse)으로 구성되어 있으며, 키와 값은 모두 객체이다. 키는 중복 저장을 허용하지 않고(Set방식), 값은 중복 저장 가능(list방식) 키가 중복된 경우, 기존에 있는 키에 해당하는 값을 덮어씌움


HashMap

키 객체는 hashCode()와 equals()를 재정의해 동등 객체가 될 조건을 정해야한다. 때문에 키 타입은 hashCode와 equals() 메소드가 재정의 되어 있는 String타입을 주로 사용한다.



Map 실습 코드

// Member.java
package com.kh.collection.map.model.vo;

public class Member {
	private String id;
	private String password;
	private String name;
	private String birthDay;
	private String phone;
	
	public Member() {
		// TODO Auto-generated constructor stub
	}

	
	public Member(String id, String password, String name, String birthDay, String phone) {
		super();
		this.id = id;
		this.password = password;
		this.name = name;
		this.birthDay = birthDay;
		this.phone = phone;
	}


	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getBirthDay() {
		return birthDay;
	}

	public void setBirthDay(String birthDay) {
		this.birthDay = birthDay;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}


	@Override
	public String toString() {
		return "Member [id=" + id + ", password=" + password + ", name=" + name + ", birthDay=" + birthDay + ", phone="
				+ phone + "]";
	}


	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((birthDay == null) ? 0 : birthDay.hashCode());
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + ((password == null) ? 0 : password.hashCode());
		result = prime * result + ((phone == null) ? 0 : phone.hashCode());
		return result;
	}


	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Member other = (Member) obj;
		if (birthDay == null) {
			if (other.birthDay != null)
				return false;
		} else if (!birthDay.equals(other.birthDay))
			return false;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (password == null) {
			if (other.password != null)
				return false;
		} else if (!password.equals(other.password))
			return false;
		if (phone == null) {
			if (other.phone != null)
				return false;
		} else if (!phone.equals(other.phone))
			return false;
		return true;
	}
}


// SetService.java
package com.kh.collection.set.model.service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;

import javax.rmi.CORBA.Stub;

import com.kh.collection.set.model.vo.Student;
import com.kh.collection.set.model.vo.Student;

public class SetService {
	
	// Set(집합)
	// - 데이터의 순서가 존재하지 않음
	// - 중복 값을 허용하지 않음 (Null도 한 번만 저장할 수 있음)
	
	public void example1() {
		// HashSet
		// - 저장되는 객체를 hashCode()를 이용하여 동일 여부를 판단
		//   --> 동일한 객체가 저장될 경우 중복 제거 진행
		
		Set<String> set = new HashSet<String>();
		
		set.add("안녕하세요");
		set.add("안녕");
		set.add("반갑습니다");
		set.add("공부하세요!");
		
		// 순서 유지 X
		System.out.println(set.toString());
		
		// 중복 데이터 X -> 중복 제거
		set.add("안녕");
		set.add(null);
		set.add(null);
		set.add(null);
		
		System.out.println(set.toString());
		
	}
	
	
	
	public void example2() {
		// HashSet, Student 사용
		// Student로 타입이 제한된 set 객체를 참조하는 참조변수 set
		//Set<Studnet> set = new HashSet<>(); // 오른쪽 Student 생략 가능 --> 타입 추론
		Set<Student> set = new LinkedHashSet<Student>();
		//LinkedHashSet : 순서를 유지한다.
		
		// 참조변수에 선언된 제네릭을 통해 생성되는 객체의 제네릭을 추론함
		
		set.add(new Student("유도리", 27, 100));
		set.add(new Student("강해", 27, 200));
		set.add(new Student("이끼", 27, 300));
		
		// 중복 삽입
		set.add(new Student("유도리", 27, 100));
		// 중복 제거를 위해서는 Student에 equals(), hashcode()가 오버라이딩 되어있어야 함
		System.out.println(set);
		
		/* hashCode
		 * - 객체에 대한 서명 또는 checksum(중복 검사)
		 *   -> 객체를 서로 구분하는 용도의 정수
		 * 
		 */
		
		// size()
		System.out.println("set 크기 : " + set.size());
		
		// remove(Student std)
//		System.out.println("삭제 성공 : " + set.remove(new Studnet("이끼", 27, 300)));
//		System.out.println(set);
		
		// set은 순서가 없기 때문에 원하는 데이터만을 꺼내보는 것이 불가능함
		//  -> 내부에 있는 모든 데이터를 무작위로 다 꺼내는 것은 가능함
		
		// 1. Set -> List로 변환
		List<Student> list = new ArrayList<Student>(set);
		
		// collection은 List와 Set의 공통점을 추출해서 만든 인터페이스 
		// collection Framework -> List, Set, Map이 포함됨
		System.out.println("Set - List로 변환");
		for(int i = 0; i < set.size(); i++) {
			System.out.println(list.get(i));
		}
		
		
		// 2. Iterator 반복자를 이용한 출력
		// 단점 : Iterator는 한 방향으로만 접근 가능함(단방향)
		// -> ListIterator(양방향)
		
		System.out.println("=========================================================");
		Iterator<Student> it = set.iterator();
		
		while(it.hasNext()) { 
			// hasNext() : 다음 반복 접근할 객체가 있을 경우 true / 없으면 false 반환
			System.out.println(it.next());
			// next() : 다음 객체를 얻어옴
			
		}
		
		// 3. 향상된 for문
		// 배열 또는 컬렉션 요소에 반복 접근하는 용도
		System.out.println("향상된 for문");
		for(Student std : set) {
			System.out.println(std);
		}
	}
	
	public void example3() {
		//TreeSet
		// - 검색 기능이 강화된 Set으로
		// 계층 구조를 활용한 이진트리 자료구조 형태의 Set
		
		// - 기본적인 Set의 특징 (순서 X, 중복 X) + 정렬
		Set<Integer> treeSet = new TreeSet<Integer>();
		
		treeSet.add(5);
		treeSet.add(15);
		treeSet.add(7);
		treeSet.add(3);
		treeSet.add(9);
		treeSet.add(8);
		System.out.println(treeSet);
	}
	
	
	public void example4() {
		// 로또 번호 생성기
		Set<Integer> lotto = new TreeSet<Integer>();
		
		while(lotto.size() < 7) {
			int random = (int)(Math.random() * 45 + 1);
			lotto.add(random);
		}
		
		System.out.println(lotto);
		
	}
	
	public void example5() {
		Set<Student> set = new TreeSet<Student>();
		
		set.add(new Student("이준호", 29, 80));
		set.add(new Student("김영주", 28, 90));
		set.add(new Student("김정화", 25, 85));
		set.add(new Student("고보석", 26, 100));
		set.add(new Student("박희도", 32, 95));
		
		for(Student std : set) {
			System.out.println(std);
		}
	}
	
	
	public void example6() {
		// 숫자 7개를 입력받아
		// 생성된 로또 번호와 몇 개가 일치하는지 출력
		
		List<Integer> lotto = new ArrayList<Integer>();
		Set<Integer> comLotto = new TreeSet<Integer>();
		Scanner sc = new Scanner(System.in);
		int count = 0;
		System.out.print("숫자 7개 입력 : ");
		while(comLotto.size() < 7) {
			if(lotto.isEmpty()) {
				for(int i = 0; i < 7; i++) {
					int num = sc.nextInt();
					lotto.add(num);
				}
			}
			int random = (int)(Math.random() *45 +1);
			comLotto.add(random);
			List<Integer> list = new ArrayList<Integer>(comLotto);
		}
		System.out.println("생성된 로또 번호 : " + comLotto);
		System.out.print("일치하는 번호 : ");
		for(int i : comLotto) {
			for(int j = 0; j < lotto.size(); j++) {
				if(i == lotto.get(j)) {
					System.out.print(i + " ");
					count++;
				}
			}
		}
		System.out.println("\ncount : " + count);
	}
	
	public void example6_1() {
		Set<Integer> inputSet = new HashSet<Integer>(); // 입력용 Set
		Set<Integer> lotto = new TreeSet<Integer>(); // 로또용 set
		List<Integer> sameNum = new ArrayList<>();
		
		
		// 1. 번호 입력
		System.out.print("숫자 7개 입력 : ");
		Scanner sc = new Scanner(System.in);
		
		while(inputSet.size() < 7) {
			inputSet.add(sc.nextInt());
		}
		
		// 2. 로또 생성 + 일치하는 카운트 + 일치 번호 저장
		int count = 0;
		while(lotto.size() < 7) {
			int random = (int)(Math.random() * 45 + 1);
			
			if(lotto.add(random)) { // Set에 정상 추가될 경우 true
				for(int input : inputSet) {
					if(input == random) {
						sameNum.add(input);
						count++;
						break;
					}
				}
			}
		}
	}
}

태그:

카테고리:

업데이트:

댓글남기기