역시나 실습보다는 이론공부가 그나마 쉽다.
실제로 사용하라고 하면 쉽지 않겠지만, 일.단. 오늘 배운 이론으로서는 이해할 수 있었다.
내일은 다른 분과 페어프로그램이 하루종일 잡혀 있던데....
내가 발목잡는 일이 없었으면..ㅜㅜ
너무 걱정 되고 민폐끼치고 싶지 않은 마음이 크지만, 일단 오늘은 내가 정해진 공부시간 내에 챕터를 끝낼 수 있었다는거에 행복감을 느낄 수 있었던 하루였다!
내일 일은 내일의 나에게..ㅎㅎ
# 열거형 (Enum)
- Enum의 기본적인 개념과, 배경, 장점에 대해 설명할 수 있다.
- Enum의 문법 요소를 이해하고 적절하게 사용할 수 있다.
# 제네릭 (Generic)
- 제네릭의 장점을 이해한다.
- 제네릭 클래스와 메서드를 정의하고 이해할 수 있다.
# 예외 처리 (Exception Handling)
- 프로그래밍에서 예외 처리가 무엇인지 이해할 수 있다.
- 컴파일 에러와 런타임 에러의 차이를 이해하고 설명할 수 있다.
- 자바 예외 클래스의 상속 계층도를 통해 클래스 간의 관계를 이해할 수 있다.
- 자바의 핵심적인 예외 처리 방법인 try-carch 문과 예외 전가에 대해 이해하고 설명할 수 있다.
- throws 와 thow 키워드의 차이에 관해 설명할 수 있다.
# 컬렉션 프레임워크 (Collection Framework)
- 컬렉션 프레임워크의 핵심 인터페이스를 이해하고 사용할 수 있다.
- 주요 인터페이스와 컬렉션 클래스의 핵심 메서드를 사용할 수 있다.
- 필요에 따라 어떤 인터페이스와 컬렉션 클래스를 사용하는 것이 적합한지 결정할 수 있다.
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
중간 레벨
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> 와 같음
// 모든 클래스 타입을 타입파라미터로 받을 수 있음
// 제한 없음
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) 기법 중 하나)
→ 예외 객체에 특정 정보를 담아 전달하기 위함
(개발자 간의 협업이나, 시스템끼리의 연동에서 사용될 수 있음)
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("입력하신 아이디가 존재하지 않습니다.");
}
}
}
// 출력 결과
아이디와 비밀번호를 입력해 주세요
아이디
Pair 연습문제
↓ 이전 글 ↓
↓ 코트스테이츠 부트캠프 관련 글 한번에 보기 ↓
[코드스테이츠] 05_04_TIL : I/O, 스트림 심화 (0) | 2023.05.04 |
---|---|
[코드스테이츠] 05_03_TIL : 애너테이션, 람다, 스트림 (1) | 2023.05.03 |
[코드스테이츠] 04_26_TIL : 객체지향 _ 다형성과 추상화 (1) | 2023.04.26 |
[코드스테이츠] 04_25_TIL : 객체지향 _ 상속과 캡슐화 (0) | 2023.04.25 |
[코드스테이츠] 04_24_TIL : 객체지향 _ 생성자와 이너클래스 (0) | 2023.04.24 |