패키지(2) java.util 의 자바 Collection <ArrayList, HashSet, HashMap, HashTable>

Yeppi's 개발 일기·2022년 5월 24일
0

JAVA

목록 보기
24/27
post-thumbnail

1. Collection

1) 개념

데이터를 한 곳에 모아놓은 곳

배열의 한계 극복

  • 배열도 일종의 컬렉션
  • 배열때문에 컬렉션이 등장하게 됨
  • 배열은 길이가 고정되어 있는 것이 가장 큰 문제
    → 배열보다 더 많은 데이터 저장해야 할때 계속 복사/카피 해야함
    → 성능이 느려짐

👉 이런 배열 한계 극복 위해 나온 것이 컬렉션

인터페이스로 구성

  • 인터페이스는 추상 메소드를 가지고 있기 때문에 객체 생성 불가
    ⇒ 이미 구현된 자식 클래스를 이용해서 사용하기
  • 최상위 부모로 사용하려고 interface 로 만듦
  • interface 끼리 상속가능(아래 구조 사진 참고)
  • 상속받은 자식은 부모 + 자기자신
    → 자식 메서드는 더 향상된 메소드를 가지고 있음


2) 구조

interface Iterable

interface Collection

interface List 👉 ArrayList

interface Set 👉 HashSet

map은 독립된 interface

interface Map 👉 HashMap, HashTable



1. ArrayList

1) 개념

  • ArrayList를 생성하면?
    10개의 저장공간 자동 생성
  • 11번째에 데이터를 추가하는 순간?
    저장공간은 자동으로 10개가 추가되어 20개가 됨
    ⇒ 배열의 단점 극복
  • 직접 공간 수 지정할 수 있음
    → 3개로 지정하더라도 add 4번째 객체 추가하면, 사이즈 자동으로 늘어남
  • 묵시적 형변환으로, 자동으로 타입 변환


2) 메서드

종류기능
size() : int등록된 객체의 개수
add(Object obj) : boolean특정 객체를 등록
등록에 성공하면 true, 실패하면 false
get(int index) : Objectindex 위치에 있는 객체
remove(int index) : Objectindex 위치에 있는 객체를 삭제하고, 삭제된 객체를 리턴
remove(Object obj) : boolean특정 객체를 삭제
삭제에 성공하면 true, 실패하면 false
contains(Object obj) : boolean특정 객체가 존재하는지 확인
객체가 있으면 true, 없으면 false
isEmplty() : boolean객체가 비어있는 지 확인

size()

  • 배열의 요소 전체 개수
  • 배열의 length 와 유사

add(93)

  • 요소 하나를 배열에 추가
  • 객체 메소드 삽입 가능
  • Integer.valueof(93)이 내부에서 자동 변환되어 저장됨
  • 앞(0번 인덱스)에서 부터 하나씩 데이터 삽입

remove(int index)

  • index 위치에 있는 요소 값 제거 후, 값 반환
  • 삭제하면 데이터는 앞으로 자리 이동

get(int index)

  • index 위치에 있는 요소 값 반환
  • ArrayList 에 데이터가 등록될 때 Object 타입으로 변환되어 저장되므로
    ⇒ 데이터를 꺼낼 때는 다시 원래의 타입으로 변환해야 함

isEmplty()

  • 배열이 비어 있는 지 확인



3) Generic 제네릭 <>

  • 모든 종류의 데이터를 저장 가능
    ⇒ Object 타입으로 데이터를 받아들이기 때문

  • 실제 프로그램에서
    타입이 다른 데이터를 컬렉션에 저장하는 경우는 거의 없음



📌예시📌

  • Generic 과 add(), get() 메서드 활용
		// <> 제네릭 => 어떤 객체를 넣을건지 지정
		// 끝에 <Book>, <> 이렇게 생략가능
		ArrayList<Book> library = new ArrayList<>();
		
		// 요소(엘리먼트)를 딱히 지정안해주면, 기본적으로 10개 잡은 후에, 늘리고 줄이고 자동으로 변경해줌 
		library.add(new Book("1", "김하나"));
		library.add(new Book("2", "이하나"));
		library.add(new Book("3", "삼하나"));
		library.add(new Book("4", "사하나"));
		library.add(new Book("5", "오하나"));
	
		for(int i=0; i<library.size(); i++) {
			library.get(i).showInfo();
		}

출력 결과

1, 김하나
2, 이하나
3, 삼하나
4, 사하나
5, 오하나


2. HashSet

1) 개념

  • ArrayList 와 완벽하게 동일

  • < > 을 사용하면 다른 타입의 객체를 저장할 수 없는 것도 똑같음

  • 순서 보장❌
  • 중복데이터 허용❌

리스트와의 차이점 및 특징은 하단을 참고해주세요



📌예시📌

  • Student 클래스의 toString() 로 출력
  • ArrayList 인 경우
ArrayList<Student> studentList = new ArrayList<Student>();
studentList.add(new Student("000005", "오예삐", 66, "운동"));
studentList.add(new Student("000001", "한예삐", 88, "게임"));
studentList.add(new Student("000002", "둘예삐", 100, "당구"));
studentList.add(new Student("000003", "삼예삐", 77, "포커"));
studentList.add(new Student("000004", "사예삐", 44, "테니스"));
studentList.add(new Student("000005", "오예삐", 66, "운동"));

System.out.println("ArrayList 인 경우");
for (Student student : studentList) {
	System.out.println(student);
}
System.out.println("");
  • Set 인 경우
Set<Student> studentList2 = new HashSet<Student>();
studentList2.add(new Student("000005", "오예삐", 66, "운동"));
studentList2.add(new Student("000001", "한예삐", 88, "게임"));
studentList2.add(new Student("000002", "둘예삐", 100, "당구"));
studentList2.add(new Student("000003", "삼예삐", 77, "포커"));
studentList2.add(new Student("000004", "사예삐", 44, "테니스"));
studentList2.add(new Student("000005", "오예삐", 66, "운동")); // 중복 값

System.out.println("HashSet 인 경우");
for (Student student2 : studentList2) {
	System.out.println(student2);
}

출력결과

  • Set 은 중복 값이 제거 되어 출력
ArrayList 인 경우
Student [studentNo=000005, name=오예삐, score=66, major=운동]
Student [studentNo=000001, name=한예삐, score=88, major=게임]
Student [studentNo=000002, name=둘예삐, score=100, major=당구]
Student [studentNo=000003, name=삼예삐, score=77, major=포커]
Student [studentNo=000004, name=사예삐, score=44, major=테니스]
Student [studentNo=000005, name=오예삐, score=66, major=운동]

HashSet 인 경우
Student [studentNo=000005, name=오예삐, score=66, major=운동]
Student [studentNo=000004, name=사예삐, score=44, major=테니스]
Student [studentNo=000002, name=둘예삐, score=100, major=당구]
Student [studentNo=000001, name=한예삐, score=88, major=게임]
Student [studentNo=000003, name=삼예삐, score=77, major=포커]


🍑ArrayList VS HashSet🍑

ArrayList

  • 넣는 데이터마다 다 저장 ⇒ 메모리 낭비 생김 ⭕
  • 순서 보장 ⭕
  • 중복 데이터 허용 ⭕

👉 단순히 목록성의 데이터를 저장하고 관리하는 용도로 사용하기에 적합

HashSet

  • 똑같은 데이터를 가진 객체는 저장하지 않음 ⇒ 메모리 낭비 ❌
  • 순서가 보장 되지 않음 ❌
  • 중복 데이터 허용 ❌


3. HashMap

1) 개념

  • (Key, Value) 항상 으로 관리됨
  • 검색이 빠름
  • value
    → 기존에 적용한 객체 타입 외에 다른 타입(new 객체)은 오류

  • Key
    → 내가 외우기 편한 문자열로 사용하는 것이 일반적
    Key 가 중복되면? 덮어써짐!

  • 원래 Key, Value 모두 Object 타입이지만
    < > 을 쓰게 되면 해당 타입에 맞춰서 사용



2) 메서드

put(“Key값”, value)

  • 데이터 저장 메소드
  • 키 값 중복 시, value 덮어쓰기(Overwriting)

remove(“Key값”)

  • value까지 같이 삭제

get("Key값”)

  • 데이터 꺼내오기, 데이터 검색하기

keySet()

  • Key 목록만 꺼내고 싶을 때
  • 반환타입 set(중복허용 X)

values()

  • value 목록만 꺼내고 싶을 때


📌예시📌

  • put(), keySet(), values() 메서드 활용하기
Map<String, Student> studentList = new HashMap<String, Student>();
// put 방식 1
Student yeppi = new Student("000001", "한예삐", 88, "게임");
studentList.put("000001", yeppi);
// put 방식 2
studentList.put("000003", new Student("000003", "삼예삐", 77, "포커"));
studentList.put("000002", new Student("000002", "둘예삐", 100, "당구"));


System.out.println("번호 목록");
Set<String> key = studentList.keySet();
for (String student : key) {
	System.out.println(student.toString());
}

System.out.println("전체 목록");
Collection<Student> information = studentList.values();
for (Student student : information) {
	System.out.println(student.toString());
}

출력결과

번호 목록
000003
000002
000001
전체 목록
Student [studentNo=000003, name=삼예삐, score=77, major=포커]
Student [studentNo=000002, name=둘예삐, score=100, major=당구]
Student [studentNo=000001, name=한예삐, score=88, major=게임]


4. HashTable

1) 개념

  • HashMap 과 동일

  • HashMap보다 HashTable이 조금 더 좋음
    자식은 부모 + 자기자신 → 즉, 더 향상된 메소드를 자식 메소드는 가지고 있기 때문



📌예시📌

  • 앞서 살펴본 HashMap과 유사한 예제
  • new Hashtable 만 다름
  • put(), keySet(), values(), remove() 메서드 활용하기
Map<String, Student> studentList = new Hashtable<String, Student>();
Student yeppi = new Student("000001", "한예삐", 88, "게임");
studentList.put("000001", yeppi);
studentList.put("000003", new Student("000003", "삼예삐", 77, "포커"));
studentList.put("000002", new Student("000002", "둘예삐", 100, "당구"));


System.out.println("번호 목록");
Set<String> key = studentList.keySet();
for (String student : key) {
	System.out.println(student.toString());
}

studentList.remove("000002");

System.out.println("전체 목록");
Collection<Student> information = studentList.values();
for (Student student : information) {
	System.out.println(student.toString());
}

출력 결과

  • 전체 목록에서는 2번 정보가 삭제된 후 출력
번호 목록
000003
000002
000001
전체 목록
Student [studentNo=000003, name=삼예삐, score=77, major=포커]
Student [studentNo=000001, name=한예삐, score=88, major=게임]


🧐Set-HashSet, Map-HashMap🧐

예제에서 타입 선언은 Set, 객체는 HashSet 이런식으로 묵시적 형변환을 시키는 이유는❓

👉 최상위 부모 타입으로 해주면, 클래스가 바뀌어도 타입 수정할 필요가 없다
👉 번거롭지 않음

👉 ex. Map 을 부모 타입으로 하는 경우, HashTable / HashMap 둘 다 변경하더라도 Map 은 별도의 소스 코드 수정이 없음

profile
imaginative and free developer. 백엔드 / UX / DATA / 기획에 관심있지만 고양이는 없는 예비 개발자👋

0개의 댓글