The A :

728x90
반응형

Today I Lean

컬렉션 (Collection)

 

 

역시나 실습보다는 이론공부가 그나마 쉽다.

실제로 사용하라고 하면 쉽지 않겠지만, 일.단. 오늘 배운 이론으로서는 이해할 수 있었다.

내일은 다른 분과 페어프로그램이 하루종일 잡혀 있던데....

내가 발목잡는 일이 없었으면..ㅜㅜ

너무 걱정 되고 민폐끼치고 싶지 않은 마음이 크지만, 일단 오늘은 내가 정해진 공부시간 내에 챕터를 끝낼 수 있었다는거에 행복감을 느낄 수 있었던 하루였다!

내일 일은 내일의 나에게..ㅎㅎ

 

 

 

학습목표 및 개념정리

# 열거형 (Enum)

- Enum의 기본적인 개념과, 배경, 장점에 대해 설명할 수 있다.

- Enum의 문법 요소를 이해하고 적절하게 사용할 수 있다.

 

# 제네릭 (Generic)

- 제네릭의 장점을 이해한다.

- 제네릭 클래스와 메서드를 정의하고 이해할 수 있다.

 

# 예외 처리 (Exception Handling)

- 프로그래밍에서 예외 처리가 무엇인지 이해할 수 있다.

- 컴파일 에러와 런타임 에러의 차이를 이해하고 설명할 수 있다.

- 자바 예외 클래스의 상속 계층도를 통해 클래스 간의 관계를 이해할 수 있다.

- 자바의 핵심적인 예외 처리 방법인 try-carch 문과 예외 전가에 대해 이해하고 설명할 수 있다.

- throws 와 thow 키워드의 차이에 관해 설명할 수 있다.

 

#  컬렉션 프레임워크 (Collection Framework)

- 컬렉션 프레임워크의 핵심 인터페이스를 이해하고 사용할 수 있다.

- 주요 인터페이스와 컬렉션 클래스의 핵심 메서드를 사용할 수 있다.

- 필요에 따라 어떤 인터페이스와 컬렉션 클래스를 사용하는 것이 적합한지 결정할 수 있다.

 

 

 

배운 것

# 열거형 (Enum)

1. 열거형 이란?

 : 여러 상수들을 보다 편리하게 선언할 수 있도록 만들어진 자바의 문법 요소

 : 서로 관련 있는 내용을 모아 한 번에 관리할 때 사용함 

 : 가짓수가 한정 된 변하지 않는 데이터를 다룰 때 사용

 → enum (enumerated type)

 → 상수 (변하지 않는 값) = final 키워드를 사용해 선언

enum Seasons {SPRING, SUMMER, FALL, WINTER}
//enum 열거형이름 (상수명1, 상수명2, 상수명3, ...}
//enum 열거형이름 {
//    SPRING, 정수값 0 할당
//    SUMMER, 정수값 1 할당
//    FALL, 정수값 2 할당
//    WINTER 정수값 3 할당
//}
// 총 4개의 열거객체를 포함한 열거형

public class Main {
    public static void main(String[] args) {
        // switch문의 조건은 
        // char, byte, short, int, Character, Byte, Short, Integer, String, enum 타입만 가능

        Seasons favoriteSeason = Seasons.WINTER;
        //열거형에 선언 된 상수에 접근하는 방법
        // 열거형이름 참조변수명 = 열거형이름.상수명;

        switch (favoriteSeason) {
            case SPRING:
                System.out.println("봄");
                break;
            case SUMMER:
                System.out.println("여름");
                break;
            case FALL:
                System.out.println("가을");
                break;
            case WINTER:
                System.out.println("겨울");
                break;

        }
    }
}

// 출력 결과
겨울

* 상수 명의 중복을 피하고, 타입에 대한 안정성을 보장 + 여러 상수들을 보다 편리하게 선언, 관리 할 수 있도록 해줌

* 훨씬 간결하고 가독성이 좋으며 switch 문에서도 작동이 가능하다.

 

 

 

2. 리턴타입

 : 아래 메서드는 모든 열거형의 조상인 java.lang.Enum 에 정의되어 있음 ( Object 클래스와 동일 개념)

리턴 타입 메서드(매개변수) 설명
String name() 열거 객체가 가지고 있는 문자열을 리턴하며,
리턴되는 문자열은 열거타입을 정의할 때 사용한 상수 이름과 동일합니다.
int ordinal() 열거 객체의 순번(0부터 시작)을 리턴합니다.
int compareTo(비교값) 주어진 매개 값과 비교해서 순번 차이를 리턴합니다.
열거 타입 valueOf(String name) 주어진 문자열의 열거 객체를 리턴합니다.
열거 배열 values() 모든 열거 객체들을 배열로 리턴합니다.
enum Level {
    LOW, // 0
    MEDIUM, // 1
    HIGH // 2
}

public class Main {
    public static void main(String[] args) {
        Level level = Level.MEDIUM;

        Level[] allLevels = Level.values(); //Values() 모든 열거 객체들을 배열로 리턴
        for(Level x : allLevels) {
            System.out.printf("%s=%d%n", x.name(), x.ordinal()); //ordinal() 열거 객체의 순번을 리턴
        }

        Level findLevel = Level.valueOf("LOW"); //valueOf("String name") 
        // valueOf("String name")주어진 문자열의 열거 객체를 리턴
        System.out.println(findLevel);
        System.out.println(Level.LOW == Level.valueOf("LOW")); 
        //리턴한 열거객체(상수)가 의도했던 것과 일치하는지 boolean 타입으로 확인
        
        switch(level) {
            case LOW:
                System.out.println("낮은 레벨");
                break;
            case MEDIUM:
                System.out.println("중간 레벨");
                break;
            case HIGH:
                System.out.println("높은 레벨");
                break;
        }
    }
}

//출력 결과
LOW=0
MEDIUM=1
HIGH=2
LOW
true
중간 레벨

 

 

 

# 제네릭 (Generic)

1. 제네릭 이란?

 : 하나의 클래스 만으로 모든 타입의 데이터를 저장 할 수 있는 인스턴스를 만들 수 있음

 : 클래스나 메서드의 코드를 작성 할 때 타입을 구체적으로 지정하는 것이 아니라, 추후에 지정할 수 있도록 일반화

 : 작성한 클래스, 메서드의 코드가 특정 데이터 타입에 얽매이지 않도록 하는 것

 → 타입지정에 제한이 없음

// Basket 클래스 정의
class Basket<T> {	
// <T> Type ;타입 매개변수
// 여러개 사용해야 할 경우 Class Basket<T, K, V> 로 사용 가능

    private T item;

    public Basket(T item) {
        this.item = item;
    }

    public T getItem() {
        return item;
    }

    public void setItem(T item) {
        this.item = item;
    }
}

public class Main {
    public static void main(String[] args) {
    
// Basket<T>에 Integer형식의 매개변수 사용
Basket<Integer> basket = new Basket<Integer>(1);
        System.out.println(basket.getItem());
    }
}

//출력값
1

 → static이 붙은 변수 또는 메서드에는 제네릭 타입 매개변수를 사용할 수 없음

 (다만, 제네릭클래스는 static 메서드를 가질 수 있다. 이 경우 static 메서드 내부는 타입 매개변수가 사용되지 않지만, 매개변수나 반환 값으로 제네릭 타입이 사용될 수는 있음)

 → 그림 그려서 첨부하기

 → 다형성 그림도 그려서 첨부하기

 

 

2. 매개변수

Class Basket<T, E, K, V, N, R>

- T ype, E lement,  K ey, V alue, N umber, R esult

 

 

 

3. 래퍼클래스 (매개변수에 치환될 타입)

- Integer (int)

 : 

 

- Double (double)

 : 

 

 

4. 제한된 제네릭클래스

 :  특정 클래스만 지정 하는 방법

 

- 특정 클래스를 상속받은 클래스만 타입으로 지정

 → extends 키워드 사용

class Flower { ... }
class Rose extends Flower { ... }
class RosePasta { ... }

// Basket 클래스의 타입으로 Flower 클래스의 하위 클래스만 지정하도록 함
class Basket<T extends Flower> {    // Flower 를 상속받는 T
    private T item;
    
		...
}

 

- 특정 인터페이스를 구현한 클래스만 타입으로 지정

 → extends 키워드 사용

interface Plant { ... }
class Flower implements Plant { ... }
class Rose extends Flower implements Plant { ... }

class Basket<T extends Plant> {
    private T item;
	
		...
}

 

- 특정 클래스를 상속받으면서, 인터페이스를 구현한 클래스를 타입으로 지정

 → extends 키워드 사용

 → 클래스를 인터페이스보다 앞에 위치시켜야 함

interface Plant { ... }
class Flower implements Plant { ... }
class Rose extends Flower implements Plant { ... }

class Basket<T extends Flower & Plant> { 
// Flower 클래스를 상속받으면서 Plant 인터페이스를 구현하는 클래스
    private T item;
	
		...
}

 

 

 

5. 제네릭 메서드

// 클래스 메서드는 클래스가 인스턴스화 될 때 타입지정이 됨
class Basket<T> {                        // 1 : 여기에서 선언한 타입 매개 변수 T와
		...

    // 제네릭 메서드는 메서드가 호출 될 때 타입지정이 됨
    public <T> void add(T element) { // 2 : 여기에서 선언한 타입 매개 변수 T는 서로 다른 것입니다.
    // 제네릭 메서드의 타입지정은 반환타입(void 등) 앞
            ...
    }
}

    Basket<String> basket = new Bakset<>(); // 위 예제의 1의 T가 String으로 지정됩니다.
    basket.<Integer>add(10);                // 위 예제의 2의 T가 Integer로 지정됩니다.
    basket.add(10);                         // 타입 지정을 생략할 수도 있습니다.

 

- Object 클래스 메서드

: 제네릭 메서드를 정의 할 때도 사용 가능한 메서드

: 나머지 메서드는 클래스의 타입이 확실해 질 때 만 사용 가능

.equals()

 

.toString()

 

 

 

6. 와일드 카드

 : 어떤 타입으로도 대체 가능

 → ?  와 extens, super 키워드를 조합하여 사용

<? extends T>
// 상한선을 제한하는 것
// T와 T를 상속받는 하위 클래스 타입만 타입파라미터로 받을 수 있도록 제한

<? super T>
// 하한선을 제한하는 것
// T와 T의 상위클래스만 타입 파라미터로 받도록 제한

<?>
// <? extens Object> 와 같음
// 모든 클래스 타입을 타입파라미터로 받을 수 있음
// 제한 없음

 

 

 

 

# 예외 처리 (Exception Handling)

1. 예외 처리란?

 : 예기치 않게 발생하는 에러에 대응할 수 있는 코드를 미리 사전에 작성하여 프로그램의 비정상적인 종료를 방지하고, 정상적인 실행 상태를 유지하기 위한 것

(에러코드만 따로 정리 예정)

 

 

 

2. Errors

 - 컴파일 에러

: 컴파일 할 때 발생하는 에러

 : 프로그램 실행 전에 발생

→ 주로 세미콜론 생략, 오탈자, 잘못된 자료형, 잘못된 포맥 등의 문법적인 문제로 생김 (Syntax Errors 라고 부르기도 함)

 → chmod [u, g, o, a][+, -, =][r, w, x] 조건에 따라 조합해서 입력

 

-  런타임 에러
 : 런타임 할 때 발생하는 에러

 : 프로그램이 실행할 때 발생

 → Read (r) 4, Write (w) 2, Execute (x) 1

 → user, group, other 순으로 권한의 값을 각각더해서 입력

 

- 에러(Error) 와 예외(Exception)

 : 한 번 발생하면 복구가 어려운 수준의 심각한 오류 ( 에러 )

 : 잘못된 사용, 미약한 수준의 오류,  코드수정으로 수습이 가능한 오류 ( 예외 )

 

 

 

3. 예외 클래스

- 일반 예외 클래스 (Exception)

 : 런타임 시 발생하는 RuntimeException 클래스와 그 하위 클래스를 제외한 모든 Exception 클래스와 그 하위 클래스들

 : 컴파일러가 코드 실행 전에 예외 처리 코드 여부를 검사한다고 하여 checked 예외라 부르기도 합

 

- 실행 예외 클래스 (Runtime Exception)

 : 앞서 언급한 런타임 시 발생하는 RuntimeException 클래스와 그 하위클래스를 지칭

 : 컴파일러가 예외 처리 코드 여부를 검사하지 않는다는 의미에서 unchecked 예외라 부르기도 합

 → 주로 개발자의 실수로 발생하는 경우가 많음 (자바 문법 요소와 관련)

 

 

 

4. try-catch문

try {
    // 예외가 발생할 가능성이 있는 코드를 삽입
} 

// catch블록은 예외 발생시 실행되는 코드로, 여러종류의 예외를 처리 할 수 있음 
// 예외가 발생하지 않으면, 실행되지 않음
// catch (ExceptionType1(예외객체) e1(참조변수)) - 참조변수는 원하는 대로 바꿔도 무방
catch (ExceptionType1 e1) {
    // ExceptionType1 유형의 예외 발생 시 실행할 코드
} 
catch (ExceptionType2 e2) {
    // ExceptionType2 유형의 예외 발생 시 실행할 코드
} 

finally {
    // finally 블록은 포함되지 않아도 무방
    // 단, 포함 되었을 시 예외 발생 여부와 상관없이 항상 실행
}

 : 위 코드 처럼 catch 블록 안에 if 문을 사용하지 않아도 예외 처리가 가능

 : 하지만 아래 코드처럼 if 문을 사용할 경우, 예외 처리를 더욱 정교하게 구현가능

try {
    // 예외가 발생할 수 있는 코드
} catch (Exception e) {
    if (e instanceof NullPointerException) {
        // NullPointerException 예외를 처리하는 코드
    } else {
        // 기타 예외를 처리하는 코드
    }
}

 

 

- 예외가 발생할 때 생성되는 예외 객체로부터 에러에 대한 정보를 얻을 수 있는 방법

 : 1

 

 : 2

 

 : 3

 

 

 

 

5. 예외 전가

 : try - catch문 외에 예외를 호출한 곳으로 다시 예외를 떠넘김

 : 메서드의 선언부 끝에 아래와 같이 throws 키워드와 발생할 수 있는 예외들을 쉼표로 구분하여서 나열해 주면 됨

// 특정 메서드에 모든 종류의 예외가 발생할 가능성이 있는 경우
// 아래와 같이 모든 예외클래스의 상위클래스인 Exception클래스를 사용해서 코드 작성

void ExampleMethod() throws Exception {
}

 

 

- throws

public class ThrowExceptionTest {

    public static void main(String[] args) {
        try {
            throwException();
        } catch (ClassNotFoundException e) {
            System.out.println(e.getMessage());
        }
    }

    static void throwException() throws ClassNotFoundException, NullPointerException {
        Class.forName("java.lang.StringX");
    }
}

//출력값
java.lang.StringX

: 결론적으로, throwException 메서드에서 발생한 ClassNotFoundException 예외는 throws 키워드를 사용하여 호출한 쪽으로 전달되었고, 호출한 쪽에서는 try-catch 문을 사용하여 해당 예외를 처리

 

 

-throw

public class ExceptionTest {

    public static void main(String[] args) {
        try {
            Exception intendedException = new Exception("의도된 예외 만들기");
            throw intendedException;
        } catch (Exception e) {
            System.out.println("고의로 예외 발생시키기 성공!");
        }
    }
    
}

//출력값
고의로 예외 발생시키기 성공!

 : Exception intendedException = new Exception 에서는 예외 객체를 생성만 하고, 예외를 발생시키지 않음

 : 그러나, throw intendedException; 구문을 사용해 해당 예외를 강제적으로 발생시킴

 → try 블록에서는 throw 키워드를 사용해 예외를 발생 시키고, 이 예외객체가 catch 블록에서 처리됨

 

* 고의로 예외를 발생시키는 이유

 → 예외 처리 메커니즘 테스트 & 디버깅

(예외가 발생했을 때 로깅하거나 복구하는 코드가 잘 작동하는지 확인)

 → 프로그램의 흐름을 변경하는데에 사용

(프로그램을 강종하거나, 현재 작업을 중단하고 다른 작업으로 전환 하는 등의 제어흐름전환(Control Flow) 기법 중 하나)

 → 예외 객체에 특정 정보를 담아 전달하기 위함

(개발자 간의 협업이나, 시스템끼리의 연동에서 사용될 수 있음)

 

 

 

 

# 컬렉션 프레임워크 (Collection Framework)

1. 컬렉션 프레임워크란?

 : 컬렉션(여러 데이터의 집합)

 : 컬렉션을 다루는 데에 있어 편리한 메서드를 미리 정의해 놓은 것

 → 특정 자료구조에 데이터를 추가, 삭제, 수정, 검색 하는 등의 동작을 수행하는 편리한 메서드를 제공

 

 

2. 주요 인터페이스

- List
 : 데이터의 순서 유지

 : 중복저장 가능

 → ArrayList, Vector, Stack, LinkedList 등

 

 

- Set
 : 데이터의 순서가 유지되지 않음

 : 중복저장 불가능

 → HashSet, TreeSet 등

 

* List와 Set은 공통점이 많아 Collection 인터페이스로 묶임

 → 다른말로 List와 Set의 공통점이 추상화 된 것이 Collection 인터페이스

 

 

- Map
 : 키(Key)와 값(Value)의 쌍으로 데이터를 저장

 : 데이터의 순서가 유지되지 않음

 → Key (값을 식별하기 위해 사용, 중복저장 불가능)

 → Value (중복저장 가능)

 → HashMap, HashTable, TreeMap, Properties 등

 

 

- Collection 인터페이스

기능 리턴 타입 메서드 설명
객체 추가 boolean add(Object o)
addAll(Collection c)
주어진 객체 및 컬렉션의 객체들을 컬렉션에 추가합니다.
객체 검색 boolean contains(Object o)
containsAll(Collection c)
주어진 객체 및 컬렉션이 저장되어 있는지를 리턴합니다.
Iterator iterator() 컬렉션의 iterator를 리턴합니다.
boolean equals(Object o) 컬렉션이 동일한지 확인합니다.
boolean isEmpty() 컬렉션이 비어있는지를 확인합니다.
int size() 저장된 전체 객체 수를 리턴합니다.
객체 삭제 void clear() 컬렉션에 저장된 모든 객체를 삭제합니다.
boolean remove(Object o)
removeAll(Collection c)
주어진 객체 및 컬렉션을 삭제하고 성공 여부를 리턴합니다.
boolean retainAll(Collection c) 주어진 컬렉션을 제외한 모든 객체를 컬렉션에서 삭제하고,
컬렉션에 변화가 있는지를 리턴합니다.
객체 변환 Object[] toArray() 컬렉션에 저장된 객체를 객체배열(Object [])로 반환합니다.
Object[] toArray(Object[] a) 주어진 배열에 컬렉션의 객체를 저장해서 반환합니다.
 

 

 

3. List<E>

- List

 : 배열과 같이 객체를 일렬로 늘어놓은 구조

 : 객체를 저장하면 자동으로 인덱스 부여, 인덱스로 객체를 검색, 추가, 삭제 가능

 → List 인터페이스에서 공통으로 사용할 수 있는 메서드

기능 리턴 타입 메서드 설명
객체 추가 void add(int index, Object element) 주어진 인덱스에 객체를 추가
boolean addAll(int index, Collection c) 주어진 인덱스에 컬렉션을 추가
Object set(int index, Object element) 주어진 위치에 객체를 저장
객체 검색 Object get(int index) 주어진 인덱스에 저장된 객체를 반환
int indexOf(Object o)
lastIndexOf(Object o)
순방향 / 역방향으로 탐색하여 주어진 객체의 위치를 반환
ListIterator listIterator()
listIterator(int index)
List의 객체를 탐색할 수 있는 ListIterator 반환
주어진 index부터 탐색할 수 있는 ListIterator 반환
List subList(int fromIndex, int toIndex) fromIndex부터 toIndex에 있는 객체를 반환
객체 삭제 Object remove(int index) 주어진 인덱스에 저장된 객체를 삭제하고 삭제된 객체를 반환
  boolean remove(Object o) 주어진 객체를 삭제
객체 정렬 void sort(Comparator c) 주어진 비교자(comparator)로 List를 정렬

 → List 인터페이스를 구현한 클래스

(ArrayList, Vector, LinkedList, Stack 등)

 

 

- ArrayList

 : 컬렉션 프레임워크에서 가장 많이 사용 됨

 : 객체를 추가하면 객체가 인덱스로 관리 됨

 : 객체 추가시 자동으로 저장용량이 늘어남

 : 데이터가 연속적으로 존재 (데이터 순서 유지)

// ArrayList에 String 객체를 추가, 검색, 삭제 하는 방법

public class ArrayListExample {
	public static void main(String[] args) {

		// ArrayList를 생성하여 list에 할당
		ArrayList<String> list = new ArrayList<String>();
        	// Linked List를 생성하여 list에 할당
		LinkedList<String> list = new LinkedList<>();

		// String 타입의 데이터를 ArrayList에 추가
		list.add("Java");
		list.add("egg");
		list.add("tree");

		// 저장된 총 객체 수 얻기
		int size = list.size(); 

		// 0번 인덱스의 객체 얻기
		String skill = list.get(0);

		// 저장된 총 객체 수 만큼 조회
		for(int i = 0; i < list.size(); i++){
			String str = list.get(i);
			System.out.println(i + ":" + str);
		}

		// for-each문으로 순회 
		for (String str: list) {
			System.out.println(str);
		}		

		// 0번 인덱스 객체 삭제
		list.remove(0);
	}
}

 

 

- LinkedList

 : 데이터를 효율적으로 추가, 삭제, 변경하기 위해 사용

 : 불연속적인 데이터가 존재하며, 데이터는 서로 연결되어 있음

 

 

- ArrayList VS LinkedList

  ArrayList LinkedList
사용하는 경우 데이터를 순차적으로 추가하거나 삭제하는 경우
(인덱스 0부터 또는, 마지막 인덱스 부터)
데이터를 중간에 추가하거나 삭제하는 경우
데이터를 불러오는 경우
결론 데이터의 개수가 변하지 않는다면 ArrayList / 데이터의 잦은 변경이 예상된다면 LinkedList

 

 

 

 

4. Interator

 : 반복자

 : 컬렉션에 저장된 요소를 순차적으로 읽어오는 역할을 함

 → Collection 인터페이스에 정의된 iterator()을 호출하면, Iteratior 타입의 인스턴스가 반환됨

 

 

- Iterator 인터페이스에 정의된 메서드

메서드 설명
hasNext() 읽어올 객체가 남아 있으면 true를 리턴하고, 없으면 false를 리턴합니다.
next() 컬렉션에서 하나의 객체를 읽어옵니다.
이때, next()를 호출하기 전에 hasNext()를 통해 읽어올 다음 요소가 있는지 먼저 확인해야 합니다.
remove() next()를 통해 읽어온 객체를 삭제합니다. next()를 호출한 다음에 remove()를 호출해야 합니다.
ArrayList<String> list = ...;
Iterator<String> iterator = list.iterator();

while(iterator.hasNext()){        // 다음 객체가 있다면
	String str = iterator.next();   // 객체를 읽어오고,
	if(str.equals("str과 같은 단어")){ // 조건에 부합한다면
		iterator.remove();            // 해당 객체를 컬렉션에서 제거합니다. 
	}
}

 

 

 

 

5. Set<E>

 : 집합 (중복값이 없음)

 : 요소의 중복을 허용하지 않음

 : 저장순서를 유지하지 않음

 → HashSet, TreeSat이 있음

기능 리턴 타입 메서드 설명
객체 추가 boolean add(Object o) 주어진 객체를 추가하고, 성공하면 true를, 중복 객체면 false를 반환합니다.
객체 검색 boolean contains(Object o) 주어진 객체가 Set에 존재하는지 확인합니다.
boolean isEmpty() Set이 비어있는지 확인합니다.
Iterator Iterator() 저장된 객체를 하나씩 읽어오는 반복자를 리턴합니다.
int size() 저장된 전체 객체의 수를 리턴합니다.
객체 삭제 void clear() Set에 저장된 모든 객체를 삭제합니다.
boolean remove(Object o) 주어진 객체를 삭제합니다.

 

 

- HashSet

 : Set 인터페이스를 구현한 가장 대표적인 컬렉션 클래스

 : 중복값을 허용하지 않고, 저장순서를 유지하지 않음

import java.util.*;

public class Main {
    public static void main(String[] args) {

				// HashSet 생성
        HashSet<String > languages = new HashSet<String>();

				// HashSet에 객체 추가
        languages.add("Java"); 
        languages.add("Python");
        languages.add("Javascript");
        languages.add("C++");
        languages.add("Kotlin");
        languages.add("Ruby");
        languages.add("Java"); // 중복

				// 반복자 생성하여 it에 할당
        Iterator it = languages.iterator();

				// 반복자를 통해 HashSet을 순회하며 각 요소들을 출력
        while(it.hasNext()) {
            System.out.println(it.next());
        }
    }
}

 

 

- TreeSet

 : 이진탐색트리 (하나의 부모노드가 최대 두개의 자식노드와 연결되는 정렬과 검색에 특화된 자료구조)

 : 데이터의 중복 저장을 허용하지 않고 저장 순서를 유지하지 않지만, 오름차순으로 나옴

 → 최상위 노드 = 루트

 → 모든 왼쪽 자식의 값이 루트나 부모보다 작고, 모든 오른쪽 자식의 값이 루트나 부모보다 큰 값을 가짐

import java.util.TreeSet;

public class TreeSetExample {
    public static void main(String[] args) {

				// TreeSet 생성
        TreeSet<String> workers = new TreeSet<>();

				// TreeSet에 요소 추가
        workers.add("Lee Java");
        workers.add("Park Hacker");
        workers.add("Kim Coding");\
        

			// TreeSet은 내부의 요소를 자동으로 정렬 함 (입력순 X) 
        System.out.println(workers);			// TreeSet에 저장된 요소를 정렬된 상태로 출력
        System.out.println(workers.first());		// TreeSet의 첫번째 요소 출력
        System.out.println(workers.last());		// TreeSet의 마지막 요소 출력
        System.out.println(workers.higher("Lee"));	// TreeSet에서 Lee 다음으로 큰 요소 출력
        System.out.println(workers.subSet("Kim", "Park"));// TreeSet에서 Kim과 Park 사이의 요소들을 출력
       
    }
}

// 출력 결과
[Kim Coding, Lee Java, Park Hacker]
Kim Coding
Park Hacker
Lee Java
[Kim Coding, Lee Java]

 

 

 

 

7. Map<K, V>

- Map

 : 키(Key)와 값(Value)으로 구성된 객체를 저장하는 구조

 : Map의 객체는 Entry라고 함

 : 이 Entry 객체는 키와 값을 각각 Key객체와 Value객체로 저장 (이때 키와 값은 모두 객체이며, 기본타입일 수 없음)

 → Key (고유한 값을 가짐)

*중복저장 불가능 (저장된 키와 같은 키로 저장을 시도하면, 새로운 값으로 덮어쓰기 됨)

 → Key가 다르면, 값이 같아도 다른 Entry로 간주

*중복저장 가능

 

 

- Map 인터페이스를 구현한 클래스에서 공통으로 사용할 수 있는 메서드

기능 리턴 타입 메서드  설명
객체 추가 Object put(Object key, Object value) 주어진 키로 값을 저장합니다.
해당 키가 새로운 키일 경우 null을 리턴하지만,
같은 키가 있으면 기존의 값을 대체하고 대체되기 이전의 값을 리턴
객체 검색 boolean containsKey(Object key) 주어진 키가 있으면 true, 없으면 false를 리턴합니다.
boolean containsValue(Object value) 주어진 값이 있으면 true, 없으면 false를 리턴합니다.
Set entrySet() 키와 값의 쌍으로 구성된 모든 Map.Entry 객체를
Set에 담아서 리턴합니다.
Object get(Object key) 주어진 키에 해당하는 값을 리턴합니다.
boolean isEmpty() 컬렉션이 비어 있는지 확인합니다.
Set keySet() 모든 키를 Set 객체에 담아서 리턴합니다.
int size() 저장된 Entry 객체의 총 갯수를 리턴합니다.
Collection values() 저장된 모든 값을 Collection에 담아서 리턴합니다.
객체 삭제 void clear() 모든 Map.Entry(키와 값)을 삭제합니다.
Object remove(Object key) 주어진 키와 일치하는 Map.Entry를 삭제하고 값을 리턴합니다.

 

 

- HashMap 

 : 삽입되는 순서와 위치는 관계없이 자동으로 저장위치를 결정함

 : 많은 양의 데이터를 검색하는데 있어 뛰어난 성능을 보임

 → HashMap 인터페이스 메소드

리턴 타입 메서드 설명
boolean equals(Object o) 동일한 Entry 객체인지 비교합니다.
Object getKey() Entry 객체의 Key 객체를 반환합니다.
Object getValue() Entry 객체의 Value 객체를 반환합니다.
int hashCode() Entry 객체의 해시코드를 반환합니다.
Object setValue(Object value) Entry 객체의 Value 객체를 인자로 전달한 value 객체로 바꿉니다.

Map은 키와 값을 쌍으로 저장하기 때문에 iterator()를 직접 호출할 수 없습니다. 그 대신 keySet()이나 entrySet() 메서드를 이용해 Set 형태로 반환된 컬렉션에 iterator()를 호출하여 반복자를 만든 후, 반복자를 통해 순회할 수 있습니다.

import java.util.*;

public class Main {
    public static void main(String[] args) {

        // HashMap 생성
        HashMap<String, Integer> map = new HashMap<>();

        // Entry 객체 저장
        map.put("피카츄", 85);
        map.put("꼬부기", 95);
        map.put("야도란", 75);
        map.put("파이리", 65);
        map.put("피존투", 15);

        // 저장된 총 Entry 수 얻기
        System.out.println("총 entry 수: " + map.size());

        // 객체 찾기
        System.out.println("파이리 : " + map.get("파이리"));

        // key를 요소로 가지는 Set을 생성 -> 아래에서 순회하기 위해 필요합니다.
        Set<String> keySet = map.keySet();

        // keySet을 순회하면서 value를 읽어옵니다.
        Iterator<String> keyIterator = keySet.iterator();
        while(keyIterator.hasNext()) {
            String key = keyIterator.next();
            Integer value = map.get(key);
            System.out.println(key + " : " + value);
        }

        // 객체 삭제
        map.remove("피존투");

        System.out.println("총 entry 수: " + map.size());

        // Entry 객체를 요소로 가지는 Set을 생성 -> 아래에서 순회하기 위해 필요합니다.
        Set<Map.Entry<String, Integer>> entrySet = map.entrySet();

        // entrySet을 순회하면서 value를 읽어옵니다.
        Iterator<Map.Entry<String, Integer>> entryIterator = entrySet.iterator();
        while(entryIterator.hasNext()) {
            Map.Entry<String, Integer> entry = entryIterator.next();
            String key = entry.getKey(); // Map.Entry 인터페이스의 메서드
            Integer value = entry.getValue(); // Map.Entry 인터페이스의 메서드
            System.out.println(key + " : " + value);
        }

        // 객체 전체 삭제
        map.clear();
    }
}

// 출력 결과
총 entry 수: 5
파이리 : 65
야도란 : 75
꼬부기 : 95
파이리 : 65
피카츄 : 85
피존투 : 15
총 entry 수: 4
야도란 : 75
꼬부기 : 95
파이리 : 65
피카츄 : 85

 

 

- Hashtable

 : HashMap과 내부구조나 사용방법은 동일

 : 구현방법이 다른 거지만, 간단하게 HashMap이 Hashtable의 새로운 버전이라고 함

import java.util.*;

public class Main {
    public static void main(String[] args){

        // HashMap 생성
        // 객체명<Key, Value> 매개변수명 = new 객체명<>();
        Hashtable<String, String> map = new Hashtable<String, String>();

        // Entry 객체 저장
        map.put("Spring", "345");
        map.put("Summer", "678");
        map.put("Fall", "91011");
        map.put("Winter", "1212");

        System.out.println(map);

        Scanner scanner = new Scanner(System.in);

        while (true) {
            System.out.println("아이디와 비밀번호를 입력해 주세요");
            System.out.println("아이디");
            String id = scanner.nextLine();

            System.out.println("비밀번호");
            String password = scanner.nextLine();

            if (map.containsKey(id)) {
                if (map.get(id).equals(password)) {
                    System.out.println("로그인 되었습니다.");
                    break;
                }
                else System.out.println("비밀번호가 일치하지 않습니다. ");
            }
            else System.out.println("입력하신 아이디가 존재하지 않습니다.");
        }
    }
}

// 출력 결과
아이디와 비밀번호를 입력해 주세요
아이디

 

 

 

 

*****

 

 

 

 

Tomorrow Chapter

Pair 연습문제

 

 

 


 

 

↓ 이전 글 ↓

2023.04.28 - [분류 전체보기] - ㅇㅇㅇ

 

↓ 코트스테이츠 부트캠프 관련 글 한번에 보기 ↓

 
728x90
반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading