220614~0616_인터넷 강의_컬렉션 프레임워크

창고·2022년 10월 20일
0

티스토리에 저장했던 글을 옮겼습니다.
https://mrcocoball.tistory.com/87
https://mrcocoball.tistory.com/88

1. 컬렉션 프레임워크

(1) 컬렉션 프레임워크

  • 자바에서 제공되는 자료 구조 구현 클래스들
  • 프로그램 구현에 필요한 자료 구조 (Data Structure)를 구현해놓은 JDK 라이브러리
  • 개발에 소요되는 시간을 절약, 최적화된 알고리즘 사용
  • 여러 구현 클래스와 인터페이스의 활용에 대한 이해 필요

(2) Collection 인터페이스

  • 하나의 객체를 관리하기 위한 메서드가 선언된 인터페이스
  • 하위에 List와 Set 인터페이스가 있음
  • List 인터페이스
    • 객체를 순서에 따라 저장하고 관리하는데 필요한 메소드가 선언된 인터페이스
    • 자료구조 리스트 (배열, 연결 리스트)의 구현을 위한 인터페이스
    • 중복 허용
    • ArrayList, Vector, LinkedList, Stack, Queue 등
  • Set 인터페이스
    • 순서와 관계 없이 중복 허용하지 않고 유일한 값을 관리하는데 필요한 메소드가 선언된 인터페이스
    • 아이디, 주민번호, 사번 등을 관리하는데에 유용
    • 저장된 순서와 출력되는 순서 다를 수 있음
    • HashSet, TreeSet 등

(3) Map 인터페이스

  • 쌍(pair) 로 이루어진 객체를 관리하는데 사용하는 메소드들이 선언된 인터페이스
  • 객체는 key-value의 쌍으로 이루어짐 (Python의 dictionary 느낌)
  • key는 중복을 허용하지 않음
  • HashTable, HashMap, Properties, TreeMap 등이 Map 인터페이스를 구현

2. List 인터페이스를 구현한 클래스와 활용

  • 순차적으로 자료를 관리하는 List 인터페이스를 구현한 클래스의 활용 방법
  • 시나리오
    • Member 클래스를 만들고 아이디와 이름을 멤버 변수로 선언
    • Member 클래스로 생성된 인스턴스들을 관리하는 클래스를 컬렉션 프레임워크 클래스들을 활용하여 구현 -> ArrayList 활용 (멤버들을 순차적으로 관리)
  • [Member.java]
public class Member {
	
	   // field

	   private int memberId; // 회원 아이디
	   private String memberName; // 회원 이름


	   // constructor

	   public Member(int memberId, String memberName) {
	      this.memberId = memberId;
	      this.memberName = memberName;
	   }

	   // getter and setter

	   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() { // toString 메소드 재정의
	      return memberName + " 학생의 아이디는 " + memberId + "입니다";
	   }

}
  • [MemberArrayList.java]
public class MemberArrayList {
	
	   // field

	   private ArrayList<Member> arrayList; // ArrayList 선언


	   // constructor

	   public MemberArrayList() {
	      arrayList = new ArrayList<Member>(); // Member로 선언한 ArrayList 생성
	   }


	   // method

	   public void addMember(Member member) { // Member 타입 member를 받아서
	      arrayList.add(member); // arrayList에 member 추가
	   }

	   public boolean removeMember(int memberId) { // memberId를 매개 변수로 삭제 여부를 반환
	   
	      for (int i=0; i<arrayList.size(); i++) { // arrayList의 0번째 인덱스의 요소부터 반복
	         Member member = arrayList.get(i); // Member 타입의 변수 member = i번째의 arrayList의 요소
	         int tempId = member.getMemberId(); // member의 memberId를 tempId로 지정
	         if(tempId == memberId) { // tempId가 위에서 매개 값으로 받은 memberId와 같다면 = 동일한 멤버라면
	            arrayList.remove(i); // i번째의 요소를 삭제
	            return true; // true 반환하며 메소드 종료
	         }
	      }
	      
	      System.out.println(memberId + "가 존재하지 않습니다"); // for문 돌렸으나 true가 반환되지 않았을 경우
	      return false; // false 반환하며 메소드 종료
	   }

	   public void showAllMember() {
	      for (Member member : arrayList) {
	         System.out.println(member);
	      }
	      System.out.println();
	   }

}
  • [MemberArrayListTest.java]
public class MemberArrayListTest {

	public static void main(String[] args) {
		MemberArrayList memberArrayList = new MemberArrayList(); // ArrayList 积己

		Member memberChika = new Member(1001, "摹墨");
		Member memberRico = new Member(1002, "府内");
		Member memberYou = new Member(1003, "夸快");
		Member memberYoshiko = new Member(1004, "夸矫内");

		memberArrayList.addMember(memberChika);
		memberArrayList.addMember(memberRico);
		memberArrayList.addMember(memberYou);
		memberArrayList.addMember(memberYoshiko);

		memberArrayList.showAllMember();

		memberArrayList.removeMember(memberYou.getMemberId());
		memberArrayList.showAllMember();

	}

}

3. 요소를 순회하는 Iterator

  • 요소의 순회 : 컬렉션 프레임워크에 저장된 요소들을 하나씩 차례로 참조하는 것을
  • 순서가 있는 List 인터페이스의 경우 Iterator를 사용하지 않고 get(i)를 활용할 수 있음
  • Set 인터페이스의 경우 get(i) 메소드가 없어 Iterator를 활용, 객체를 순회
  • Iterator 사용 방법
    • boolean hasNext() : 이후에 요소가 더 있는지를 체크하는 메소드, 요소가 있으면 true를 반환
    • E next() : 다음에 있는 요소를 반환
  • 위에서의 removeMember() 메소드를 Iterator를 활용하여 구현
public class MemberArrayListIterator {
	
	   // field

	   private ArrayList<Member> arrayList; // ArrayList 선언


	   // constructor

	   public MemberArrayListIterator() {
	      arrayList = new ArrayList<Member>(); // Member로 선언한 ArrayList 생성
	   }


	   // method

	   public void addMember(Member member) { // Member 타입 member를 받아서
	      arrayList.add(member); // arrayList에 member 추가
	   }

	   public boolean removeMember(int memberId) { // memberId를 매개 변수로 삭제 여부를 반환
	   
		     Iterator<Member> ir = arrayList.iterator(); // member 대상으로 한 이터레이터 생성 (맨 처음 인덱스 바로 앞에 생성)
		     while(ir.hasNext()) { // ir.hasNext()가 true이면 반복 = ir 뒤에 요소가 더 있으면 계속 반복
		        Member member = ir.next(); // Member 타입의 변수 member = ir 뒤에 있는 요소 (요소를 순회)
		        int tempId = member.getMemberId(); // member의 memberId를 tempId로 지정
		        if(tempId == memberId) { // tempId가 위에서 매개 값으로 받은 memberId와 같다면 = 동일한 멤버라면
		            arrayList.remove(member); // arrayList에서 member를 삭제
		            return true; // true 반환
	         }
	      }
	      
	      System.out.println(memberId + "가 존재하지 않습니다"); // while문 돌렸으나 true가 반환되지 않았을 경우
	      return false; // false 반환하며 메소드 종료
	   }

	   public void showAllMember() {
	      for (Member member : arrayList) {
	         System.out.println(member);
	      }
	      System.out.println();
	   }

}

4. Set 인터페이스 구현 클래스와 활용

(1) HashSet 클래스

  • Set 인터페이스를 구현한 클래스
  • 멤버의 중복 여부를 체크하기 위해 인스턴스의 동일성 확인 필요
  • 동일성 구현을 위해 필요에 따라 equals()와 hashCode() 메소드 재정의
  • [MemberHashSet.java]
public class MemberHashSet {
	
	   // field

	   private HashSet<Member> hashSet; // HashSet 선언


	   // constructor

	   public MemberHashSet() {
	      hashSet = new HashSet<Member>(); // Member로 선언한 HashSet 생성
	   }


	   // method

	   public void addMember(Member member) { // Member 타입 member를 받아서
	      hashSet.add(member); // hashSet에 member 추가
	   }

	   public boolean removeMember(int memberId) { // memberId를 매개 변수로 삭제 여부를 반환
	   
		      Iterator<Member> ir = hashSet.iterator(); // hashSet에 대한 이터레이터 생성

		      while(ir.hasNext()) { // 이터레이터 순회 반복 (다음 요소가 존재할 때까지)
		         Member member = ir.next(); // 이터레이터 이동
		         int tempId = member.getMemberId();
		         if (tempId == memberId) {
		            hashSet.remove(member);
		            return true;
	         }
	      }
	      
	      System.out.println(memberId + "가 존재하지 않습니다"); // while문 돌렸으나 true가 반환되지 않았을 경우
	      return false; // false 반환하며 메소드 종료
	   }

	   public void showAllMember(){
			for(Member member : hashSet){
				System.out.println(member);
			}
			System.out.println();

	   }

}
  • [Member.java]
public class Member {
	
	   // field

	   private int memberId; // 회원 아이디
	   private String memberName; // 회원 이름


	   // constructor

	   public Member(int memberId, String memberName) {
	      this.memberId = memberId;
	      this.memberName = memberName;
	   }

	   // getter and setter

	   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() { // toString 메소드 재정의
	      return memberName + " 학생의 아이디는 " + memberId + "입니다";
	   }

	   @Override // hashCode를 memberId로 반환하게끔 재정의
	   public int hashCode() {
		  return memberId;
	   }

	   @Override // 논리적 위치 = hashCode가 같을 경우 동일한 객체로 판정하게끔 재정의
	   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;
	   }

	   
}

-> 인스턴스의 동일성 확보를 위해 hashCode() 및 equals() 메소드 재정의

  • [MemberHashSetTest.java]
public class MemberHashSetTest {

	public static void main(String[] args) {
		MemberHashSet memberHashSet = new MemberHashSet(); // HashSet 생성

		Member memberChika = new Member(1001, "치카");
		Member memberRico = new Member(1002, "리코");
		Member memberYou = new Member(1003, "요우");
		Member memberYoshiko = new Member(1004, "요시코");

		memberHashSet.addMember(memberChika);
		memberHashSet.addMember(memberRico);
		memberHashSet.addMember(memberYou);
		memberHashSet.addMember(memberYoshiko);

		memberHashSet.showAllMember();
		
		Member memberHanamaru = new Member(1004, "하나마루"); // ID가 동일하므로 동일 객체 판정 필요
		memberHashSet.addMember(memberHanamaru);
		
		memberHashSet.showAllMember();		

	}

}

5. 정렬을 위해 Comparable과 Comparator 인터페이스 구현

(1) TreeSet 클래스 활용

  • 객체의 정렬에 사용하는 클래스
  • Set 인터페이스를 구현, 중복을 허용하지 않고 오름차순/내림차순으로 객체 정렬 가능
  • 내부적으로 이진 검색트리(binary search tree)로 구현
  • 이진 검색트리에 저장하기 위해 각 객체 비교 필요
  • 비교 대상이 되는 객체에 Comparable이나 Comparator 인터페이스 구현해야 TreeSet에 추가 가능
  • String, Integer 등 JDK의 많은 클래스들이 이미 Comparable을 구현함
  • [MemberTreeSet.java]
public class MemberTreeSet {
	
	   // field

	   private TreeSet<Member> treeSet; // treeSet 선언


	   // constructor

	   public MemberTreeSet() {
	      treeSet = new TreeSet<Member>(); // Member로 선언한 treeSet 생성
	   }


	   // method

	   public void addMember(Member member) { // Member 타입 member를 받아서
	      treeSet.add(member); // treeSet에 member 추가
	   }

	   public boolean removeMember(int memberId) { // memberId를 매개 변수로 삭제 여부를 반환
	   
		      Iterator<Member> ir = treeSet.iterator(); // treeSet에 대한 이터레이터 생성

		      while(ir.hasNext()) { // 이터레이터 순회 반복 (다음 요소가 존재할 때까지)
		         Member member = ir.next(); // 이터레이터 이동
		         int tempId = member.getMemberId();
		         if (tempId == memberId) {
		            treeSet.remove(member);
		            return true;
	         }
	      }
	      
	      System.out.println(memberId + "가 존재하지 않습니다"); // while문 돌렸으나 true가 반환되지 않았을 경우
	      return false; // false 반환하며 메소드 종료
	   }

	   public void showAllMember(){
			for(Member member : treeSet){
				System.out.println(member);
			}
			System.out.println();

	   }

}
  • [MemberTreeSetTest.java]
public class MemberTreeSetTest {

	public static void main(String[] args) {
		
		MemberTreeSet memberTreeSet = new MemberTreeSet(); // TreeSet 생성
		
		Member memberHanamaru = new Member(1005, "하나마루"); // ID가 동일하므로 동일 객체 판정 필요
		Member memberChika = new Member(1001, "치카");
		Member memberRico = new Member(1002, "리코");
		Member memberYou = new Member(1003, "요우");
		Member memberYoshiko = new Member(1004, "요시코");

		memberTreeSet.addMember(memberChika);
		memberTreeSet.addMember(memberRico);
		memberTreeSet.addMember(memberYou);
		memberTreeSet.addMember(memberYoshiko);
		memberTreeSet.addMember(memberHanamaru);
		memberTreeSet.showAllMember();
			
	}

}

  • Comparable / Comparator가 구현되지 않을 경우 위와 같은 오류 발생
    → Member 클래스가 아이디 내림차순으로 정렬되게 하기 위해 Comparable 인터페이스 구현
  • [Member.java] - Comparable<타입> 을 implements, compareTo (타입 변수) 재정의
public class Member implements Comparable<Member> {
	
	   // field

	   private int memberId; // 회원 아이디
	   private String memberName; // 회원 이름


	   // constructor

	   public Member(int memberId, String memberName) {
	      this.memberId = memberId;
	      this.memberName = memberName;
	   }

	   // getter and setter

	   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() { // toString 메소드 재정의
	      return memberName + " 학생의 아이디는 " + memberId + "입니다";
	   }

	   @Override // hashCode를 memberId로 반환하게끔 재정의
	   public int hashCode() {
		  return memberId;
	   }

	   @Override // 논리적 위치 = hashCode가 같을 경우 동일한 객체로 판정하게끔 재정의
	   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;
	   }
	   
	   @Override
	   public int compareTo(Member member) { // 반환값이 int, 본인과 비교값을 비교, 본인이 클 경우 양수, 같으면 0, 작으면 음수

	      // return (this.memberId - member.memberId); // 오름차순
	      return (this.memberId - member.memberId) * (-1); // 내림차순

	   }
	   
	   
}
  • [MemberTreeSetTest.java]
public class MemberTreeSetTest {

	public static void main(String[] args) {
		
		MemberTreeSet memberTreeSet = new MemberTreeSet(); // TreeSet 생성
		
		Member memberHanamaru = new Member(1005, "하나마루"); // ID가 동일하므로 동일 객체 판정 필요
		Member memberChika = new Member(1001, "치카");
		Member memberRico = new Member(1002, "리코");
		Member memberYou = new Member(1003, "요우");
		Member memberYoshiko = new Member(1004, "요시코");

		memberTreeSet.addMember(memberChika);
		memberTreeSet.addMember(memberRico);
		memberTreeSet.addMember(memberYou);
		memberTreeSet.addMember(memberYoshiko);
		memberTreeSet.addMember(memberHanamaru);
		memberTreeSet.showAllMember();
			
	}

}
  • 주로 Comparable을 사용함

(2) Comparator의 활용

  • 이미 Comparable이 구현된 경우 Comparator로 비교하는 방식을 다시 구현할 수 있음 (String의 Comparable을 변경)
class MyCompare implements Comparator<String> {
	
	@Override
	public int compare(String s1, String s2) {
		return (s1.compareTo(s2)) * -1; // s1 - s2 값 * -1 = 내림차순으로 정렬
	}
}

public class ComparatorTest {

	public static void main(String[] args) {
		
		TreeSet <String>set = new TreeSet<String>(new MyCompare());
		set.add("가오가이가");
		set.add("나오나이나");
		set.add("다오다이다");
		
		System.out.println(set);

	}

}

3. 쌍(pair) 로 자료를 관리하는 Map 인터페이스를 구현한 클래스와 활용

(1) HashMap 클래스 활용

  • Map 인터페이스를 구현한 클래스와
  • 가장 많이 사용되는 Map 인터페이스 기반 클래스
  • key - value를 쌍으로 관리하는 메소드를 구현
  • 검색을 위한 자료 구조
  • key를 이용하여 값을 저장하고 key를 이용, 값을 꺼내오는 방식 - hash 알고리즘으로 구현
  • key가 되는 객체는 중복이 불가, 객체의 유일성을 비교하기 위한 equals(), hashCode() 메소드 구현 필요
  • [MemberHashMap.java]
public class MemberHashMap {
	
	   // field

	   private HashMap<Integer, Member> hashMap; // hashMap 선언


	   // constructor

	   public MemberHashMap() {
	      hashMap = new HashMap<>(); // Member로 선언한 hashMap 생성
	   }


	   // method

	   public void addMember(Member member) { // Member 타입 member를 받아서
	      hashMap.put(member.getMemberId(), member); // hashMap에 member의 memberId와(key) member(value) 추가
	   }

	   public boolean removeMember(int memberId) { // memberId를 매개 변수로 삭제 여부를 반환
	   
		  if (hashMap.containsKey(memberId)) { // hashMap의 키에 memberId가 있을 경우
		    	 hashMap.remove(memberId); // 해당 key-value를 지워버림
		  }
		     	      
	      System.out.println(memberId + "가 존재하지 않습니다"); // while문 돌렸으나 true가 반환되지 않았을 경우
	      return false; // false 반환하며 메소드 종료
	   }

	   public void showAllMember(){
		   
		   Iterator<Integer> ir = hashMap.keySet().iterator(); // hashMap의 keySet 한 것에 이터레이터 생성
		   
		   while(ir.hasNext()) { // 이터레이터 순회
			   
			   int key = ir.next(); // 키 추출
			   Member member = hashMap.get(key); // 키에 대한 값 추출하여 member에 저장
			   System.out.println(member);
		   }

			System.out.println();

	   }

}
  • [MemberHashMapTest.java]
public class MemberHashMapTest {

	public static void main(String[] args) {
		
		MemberHashMap memberHashMap = new MemberHashMap(); // HashMap 생성
		
		Member memberHanamaru = new Member(1005, "하나마루"); // ID가 동일하므로 동일 객체 판정 필요
		Member memberChika = new Member(1001, "치카");
		Member memberRico = new Member(1002, "리코");
		Member memberYou = new Member(1003, "요우");
		Member memberYoshiko = new Member(1004, "요시코");

		memberHashMap.addMember(memberChika);
		memberHashMap.addMember(memberRico);
		memberHashMap.addMember(memberYou);
		memberHashMap.addMember(memberYoshiko);
		memberHashMap.addMember(memberHanamaru);
		memberHashMap.showAllMember();
		
		HashMap<Integer, String> hashMap = new HashMap<Integer, String>();
		hashMap.put(1006, "루비");
		hashMap.put(1007, "다이아");
		System.out.println(hashMap);
			
	}

}

(2) TreeMap 클래스

  • Map 인터페이스를 구현한 클래스, key에 대한 정렬을 구현할 수 있음
  • key가 되는 클래스에 Comparable이나 Comparator 인터페이스를 구현,
    key-value 쌍의 자료를 key 값을 기준으로 하여 정렬할 수 있음
profile
공부했던 내용들을 모아둔 창고입니다.

0개의 댓글