열거형 (Enum)
여러 상수들을 보다 편리하게 선언할 수 있도록 만들어진 자바의 문법 요소.
학습 목표
- Enum의 기본적인 개념을 이해하고 설명할 수 있다.
관련된 상수들을 같이 묶어놓은것 java 타입에 안전한 열거형을 제공
enum 계절 { 봄, 여름, 가을, 겨울}
enum 날씨 {맑음, 흐림,눈,비}
if (계절.봄 == 날씨.맑음) // 컴파일 에러 값은 둘다 0번째여서 같지만 타입이 달라서 비교 불가 (값과 타입을 모두 체크함)
- Enum이 등장하게 된 배경에 대해서 이해하고, 그 장점에 대해 설명할 수 있다.
- Enum의 문법 요소를 이해하고 적절하게 사용할 수 있다.
정의 하는 방법
enum 열거형이름{상수명1,상수명2, . . .}
열거형 상수의 배교에 ==와 compareTo()사용가능 ,> < 등 비교 연산자 사용 불가능
CompareTo() 왼쪽이 크면 양수 ,같으면 0 , 오른쪽이 크면 음수
열거형 함수는 객체라서 equals로 같은지 틀린지 확인할 수 있음. 봄.equals(봄) >> true가 반환됨
예를 들어compareTo()를 사용하면 봄.compareTo(겨울) 일경우 봄은 0 겨울은 2 이므로 -2 가 출력이됨.
상수는 대소문자로 모두 작성이 가능하지만 관례적으로 대문자로 작성합니다.
열거형에 선언된 상수에 접근하는 방법은 열거형이름.상수명 을 통해서 가능합니다.
리턴 타입메소드(매개변수) 설명
String | name() | 열거 객체가 가지고 있는 문자열을 리턴하며, 리턴되는 문자열은 열거타입을 정의할 때 사용한 상수 이름과 동일합니다. |
int | ordinal() | 열거 객체의 순번(0부터 시작)을 리턴합니다. |
int | compareTo(비교값) | 주어진 매개값과 비교해서 순번 차이를 리턴합니다. |
열거 타입 | valueOf(String name) | 주어진 문자열의 열거 객체를 리턴합니다. |
열거 배열 | values() | 모든 열거 객체들을 배열로 리턴합니다. |
제네릭(Generic)
학습목표
- 제네릭의 장점을 이해한다.
하나의 클래스 만으로 모든 타입의 데이터를 저장 할 수 있는 인스턴스를 만들 수 있다.
타입을 구체적으로 지정하는것이 아니라 추후에 지정할 수 있도록 일반화 하는것을 의미하며 작성한 클래스 또는 메서드의 코드가 특정 데이터 타입에 얽메이지 않게 해둔것을 의미한다.
래퍼클래스란?
integer와 int의 차이
- 제네릭 클래스를 정의하고 활용할 수 있다.
제네릭이 사용 된 클래스를 제네릭 클래스라한다. T를 타입 매개변수라고 하며 <T>와 같이 꺽쇠 안에 넣어 클래스 이름 옆에 작성해줌으로 써 내부에서 사용 할 타입 매개 변수를 선언할 수 있다.
만약 <>안에 Integer를 넣어 인스턴스화 한다면 클래스 내부의 T는 모두 Integer로 치환된다.
제네릭 클래스에서 타입 매개변수를 임의의 타입으로 사용할수 있지만 클래스 변수에는 타입 매개변수를 사용할 수 없습니다.
private T phone. // O static T phone. // X
클래스 변수는 모든 인스턴스가 공유하는 변수여서 클래스 변수에 타입 매개변수를 사용할 수 있따면 클래스 변수의 타입이 인스턴스별로 달라지게 되기때문이다.
즉 클래스 변수에 타입 매개변수를 사용 할 수 있다면, Phone<String>으로 만든 인스턴스와 Phone<Integer>로 만든 인스턴스가 공유하는 클래스 변수의 타입이 서로 달라지게 되어 클래스 변수를 통해 같은 변수를 공유하는 것이 아니게 됩니다.
- 제네릭 메서드를 정의하고 활용할 수 있다.
클래스 전체를 제네릭으로 선언할 수도 있지만 클래스 내부의 특정 메서드만 제네릭으로 선언할 수 있다 이것을 제네릭 메서드라고 한다.
클래스명 옆에서 선언한 타입 매개변수는 클래스가 인스턴스화 될 때 타입이 지정됩니다.
그러나 제네릭 메서드의 타입 지정은 메서드가 호출 될 때 이루어집니다.
- 와일드 카드
어떠한 타입으로든 대체될 수 있는 타입파라미터를 의미하며 기호 ?로 와일드 카드를 사용할 수 있다.
와일드 카드에는 extend Object가 포함되어있다
<? extend T>는 와일드 카드에 상한 제한을 두는것으로 T와 T를 상속받는 하위클래스 타입만 타입 파라미터로 받을수 있도록 지정합니다
<? super T>는 와일드카드에 하한을 제한두는것으로, T와T의 상위 클래스만 타입 파라미터로 받도록 합니다.
예외처리(Exception Handling)
학습 목표
- 프로그래밍에서 예외 처리가 무엇인지 이해할 수 있다.
의도한대로 작동하지 않거나 심각한 경우 비정상적으로 종료되게됩니다.
프로그램의 비정상적인 종료를 방지하고 정상적인 실행상태를 유지하기 위해 사용됨.
- 컴파일 에러와 런타임 에러의 차이를 이해하고 설명할 수 있다.
자바에서는 발생 시점에 따라 컴파일에러, 런타임에러로 구분하고있다.
컴파일에러는 말그대로 컴파일 할 때 발생하는 에러로 자바 컴파일러가 오류를 감지하여 사용자에게 친절히 알려주기 때문에 상대적으로 쉽게 발견하고 수정할 수 있다.
런타임에러는 프로그램이 실행될때 만나게되는 에러입니다.
에러와 예외
에러란 한번 발생하면 복구하기 어려운 수준의 심각한 오류를 의미하고 대표적으로 메모리 부족과 스택 오버플로우 등이 있습니다.
예외란 잘못된 사용 또는 코딩으로 인한 상대적으로 미약한 수준의 오류로써 코드 수정등을 통해 수습이 가능한 오류를 지칭합니다.
- 자바 예외 클래스의 상속 계층도를 통해 클래스 간 관계를 이해할 수 있다.
자바에서는 예외가 발생하면 예외 클래스로부터 객체를 생성하여 해당 인스턴스를 통해 예외처리를한다.
자바의 모든 에러와 예외 클래스는 Throwable클래스로부터 확장되며 모든 예외의 최고상위클래스는 Exception클래스입니다.
Exception클래스는 일반예외 클래스와 실행 예외클래스로 나뉜다
일반예외클래스 (Exception)
런타임 시 발생하는 RuntimeException클래스와 그 하위 클래스를 제외한 모든 Exception클래스와 그 하위 클래스들을 가리킵니다.
컴파일러가 코드 실행전에 예외 처리 코드 여부를 검사한다고하여 checked예외라 부르기도합니다.
주로 잘못된 클래스명이나 데이터형식등 사용자 편의실수로 발생하는 경우가 많습니다.
싱행예외클래스(Runtime Exception)
런타임 시 발생하는 RuntimeException 클래스와 그 하위 클래스를 지칭합니다.
컴파일러가 예외 처리코드 여부를 검사하지 않는다는 의미에서 unchecked예외라 부르기도 합니다.
주로 개발자의 실수에 의해 발생하는 경우가 많고, 자바 문법 요소와 관련이 있습니다.
예컨대, 클래스 간 형변환오류, 벗어난 배열 범위 지정, 값이 null인 참조변수 사용 등이 있습니다.
- 자바의 핵심적인 예외처리 방법인 try-catch 문과 예외 전가에 대해 이해하고 설명할 수 있다.
try-catch문
try안에 예외가 발생할 가능성이 있는 코드를 삽입합니다.
만약 작성한 코드가 예외없이 정상적으로 실행되면 catch 블럭은 실행되지 않고 finally블럭이 실행된다.
finally블럭은 옵션으로 필수적으로 포함되지 않아도 되지만 만약 포함되는경우에는 예외 발생 여부와 상관없이 항상 실행되게 됩니다.
catch블럭은 예외가 발생하는 경우에 실행되는 코드로, 여러 종류의 예외처리를 할 수 있습니다.
- throws 키워드와 throw 키워드의 차이에 대해 설명할 수 있다.
예외를 떠넘기려면 메서드의 선언부 끝에 throws키워드와 발생할 수 있는 예외들을 쉼표로 구분하여 나열해 주면됩니다.
반환타입 메서드명(매개변수, ...) throws 예외클래스1,예외클래스2 ... {
...생략.... }
예를 들면 특정 메서드에서 모든 종류의 메서드가 발생할 가능성이 있는 경우 (예외)
>> void ExampleMethod() throws Exception{}
컬렉션 프래임워크(Collection Framework)
stack은 프링글스 통 >> 후인선출 마지막에넣은것이 먼저 나옴
큐 >>먼저들어온사람이 먼저나감
트리 >>
컬렉션(동적)과 배열(정적)의 차이
컬렉션은 메모리의 빈공간에 들어가는반면, 배열은 연속된 빈공간이 있어야 들어가짐 > 컬렉션은 데이터 추가가 가능하지만 배열은 추가가 안됨.
배열은 읽을땐 빠르고 데이터를 넣을땐 안좋고, 컬렉션은 읽을때 느리고 데이터 넣을땐 좋다.
학습목표
- 컬렉션 프레임워크의 핵심 인터페이스를 이해하고 사용할 수 있다.
List -
List는 데이터의 순서가 유지되며, 중복 저장이 가능한 컬렉션을 구현하는데 사용된다.
Set-
set은 데이터 순서가 유지되지 않으며 중복 저장이 불가능한 컬렉션을 구현하는데 사용된다.
Map-
Map은 키(Key)와 값(Value)의 쌍으로 데이터를 저장하는 컬렉션을 구현하는데 사용된다.
데이터의 순서가 유지되지 않으며 ,키는 값을 식별하기 위해 사용되므로 중복 저장이 불가능하지만, 값은 중복저장이 가능합니다.
이 셋 중에서 List와 Set은 서로 공통점이 많아 위 그림과 같이 Collection이라는 인터페이스로 묶입니다. 즉, 이 둘의 공통점이 추출되어 추상화된 것이 바로 Collection이라는 인터페이스입니다.
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) | 주어진 배열에 컬렉션의 객체를 저장해서 반환합니다.
|
- 주요 인터페이스와 컬렉션 클래스의 핵심 메서드를 사용할 수 있다.
List <E>
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를 정렬 |
ArrayList
ArrayList는 List 인터페이스를 구현한 클래스로, 컬렉션 프레임워크에서 가장 많이 사용된다. 기능적으로는 Vector와 동일하지만 기존의 Vector를 개선한 것이므로 Vector보다 주로 ArrayList를 사용한다.
ArrayList에 객체를 추가하면 객체가 인덱스로 관리된다는 점에서 배열과 유사하다. 그러나 배열은 생성될 때 크기가 고정되어 크기를 변경할 수 없는 반면 ArrayList는 저장 용량을 초과하여 객체들이 추가되면 자동으로 저장용량이 늘어나게 된다. 또한 리트스 계열 자료구조의 특성을 이어받아 데이터가 연속적으로 존재한다.
ArrayList를 생성하기 위해서는 저장할 객체 타입을 타입 매개변수, 즉 제네릭으로 표기하고 기본생성자를 호출한다.
ArrayList<타입 매개변수> 객체명 = new ArrayList<타입 매개변수>(초기 저장 용량);
ArrayList<String> container1 = new ArrayList<String>();
// String 타입의 객체를 저장하는 ArrayList 생성
// 초기 용량이 인자로 전달되지 않으면 기본적으로 10으로 지정됩니다.
ArrayList<String> container2 = new ArrayList<String>(30);
// String 타입의 객체를 저장하는 ArrayList 생성
// 초기 용량을 30으로 지정하였습니다.
ArrayList에 객체를 추가하면 인덱스 0부터 차례대로 저장된다. 그리고 특정 인덱스의 객체를 제거하면, 바로 뒤 인덱스 부터 마지막 인덱스까지 모두 앞으로 1씩 당겨진다
따라서 빈번한 객체 삭제와 삽입이 일어나는 곳에서는 ArrayList보다 LinkedList를 사용하는것이 좋다.
//ArrayList에 String객체를 추가 검색 삭제 하는 예제
public class ArrayListExample {
public static void main(String[] args) {
// ArrayList를 생성하여 list에 할당
ArrayList<String> list = new ArrayList<String>();
// 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
LinkedList 컬렉션은 데이터를 효율적으로 추가 삭제 변경 하기 위해 사용합니다. 배열에는 모든 데이터가 연속적으로 존재하지만 LinkedList에는 불연속적으로 존재하며 이 데이터는 서로 연결(Link)되어있습니다.
LinkedList에서 데이터를 삭제 하려면 삭제하고자 하는 요소의 이전 요소가 삭제하고자 하는 요소의 다음 요소를 참조하도록 변경됩니다. 링크를 끊어주는 방식이라 생각하면 된다. 배열처럼 데이터를 이동하기 위해 복사할 필요가 없기 때문에 처리속도가 훨씬 빠르다.
데이터를 추가할 때에도 새로운 요소를 추가하고자 하는 위치의 이전 요소와 다음 요소 사이에 연결해 주면된다.
ArrayList 와 RinkedList의 차이
ArrayList에서 데이터를 추가하는 상황이다 ArrayList에서 데이터를 추가 또는 삭제하려면 그림과 같이 데이터를 복사해서 이동해야한다 객체를 순차적으로 저장할 때는 데이터를 이동하지 않아도 되므로 작업속도가 빠르지만 중간에 위치한 객체를 추가 및 삭제할때에는 데이터 이동이 많이 일어나므로 속도가 저하된다.
인덱스가 n인 데이터 주소 = 배열의 주소 + n * 데이터 타입의 크기 //를 계산하여 데이터에 빠르게 접근이 가능하기 때문에 검색(읽기)측면에서는 유리하다
장점 : 데이터를 순차적으로 추가하거나 삭제하는 경우
데이터를 읽어들이는 경우
단점: 중간에 데이터를 추가하거나 삭제하는경우
LinkedList는 데이터를 중간에 추가하거나 삭제하는 경우 ArrayList보다 빠른속도를 보여주지만 검색에선 상대적으로 느리다.
결론 : 데이터의 잦은 변경이 예상되면 LinkedList , 데이터 갯수가 변하지 않는다면 ArrayList
Iterator
컬렉션에 저장된 요소들을 순차적으로 읽어오는 역할을 함
Collection 인터페이스에 정의된 Iterator()를 호출하면, Iterator 타입의 인스턴스가 반환된다.
메서드 설명
hasNext() | 읽어올 객체가 남아 있으면 true를 리턴하고, 없으면 false를 리턴합니다. |
next() | 컬렉션에서 하나의 객체를 읽어옵니다. 이 때, next()를 호출하기 전에 hasNext()를 통해 읽어올 다음 요소가 있는지 먼저 확인해야 합니다. |
remove() | next()를 통해 읽어온 객체를 삭제합니다. next()를 호출한 다음에 remove()를 호출해야 합니다. |
Iterator를 활용하여 컬렉션의 객체를 읽어올 때에는 next() 메서드를 사용합니다. next() 메서드를 사용하기 전에는 먼저 가져올 객체가 있는지 hasNext()를 통해 확인하는 것이 좋습니다.
hasNext() 메서드는 읽어올 다음 객체가 있으면, true를 리턴하고, 더 이상 가져올 객체가 없으면 false를 리턴합니다. 따라서 true가 리턴될 때에만 next()메서드가 동작하도록 코드를 작성해야 합니다.
Set<E>
요소의 중복을 허용하지 않고, 저장 순서를 유지하지 않는 컬렉션입니다.
Set 인터페이스에 정의된 메서드들은 다음과 같습니다.
기능 리턴타입 메서드 설명객체 추가 | 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-
중복된 값을 허용하지 않으며 저장 순서를 유지하지 않음.
TreeSet-
이진 탐색 트리 형태로 데이터를 저장한다. 데이터의 중복 저장을 허용하지 않고 저장 순서를 유지하지 않는 Set 인터페이스의 특징은 그대로 유지됨.
이진 탐색 트리란 하나의 부모 노드가 최대 두개의 자식 노드와 연결되는 이진트리의 일종으로 정렬과 검색에 특화된 자료 구조입니다.
최상위 노드를 루트라고하고 이진 탐색트리는 모든 왼쪽 자식의 값이 루트나 부모보다 작고, 모든 오른쪽 자식의 값이 루트나 부모보다 큰 값을 가지는 특징이 있다.
Map<K,V>
Map 인터페이스는 키(key)와 값(value)으로 구성된 객체를 저장하는 구조를 가지고 있습니다. 여기서 이 객체를 Entry객체라고 하는데, 이 Entry 객체는 키와 값을 각각 Key 객체와 Value 객체로 저장합니다.
키는 중복 저장 될 수 없지만, 값은 중복 저장이 가능하다.
기존에 저장된 키와 동일한 키로 값을 저장하면 기존의 값이 새로운 값으로 바뀐다.
기능 리턴타입 메서드 설명
객체 추가 | 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은 Map인터페이스를 구현한 대표적인 클래스이다 HashMap은 키와 값으로 구성된 객체를 저장하는데 이 객체를 Entry객체라한다.
HashMap의 개별요소가 되는 Entry 객체는 Map 인터페이스의 내부 인터페이스인 Entry인터페이스를 구현하며, Map.Entry는 다음과 같은 메서드가 정의되어있습니다.
Map은 키와 값을 쌍으로 저장하기 때문에 iterator()를 직접 호출할 수 없습니다. 그 대신 keySet() 이나 entrySet() 메서드를 이용해 Set 형태로 반환된 컬렉션에 iterator()를 호출하여 반복자를 만든 후, 반복자를 통해 순회할 수 있습니다.
- 필요에 따라 어떤 인터페이스와 컬렉션 클래스를 사용하는 것이 적합한지 결정할 수 있다.
'TIL' 카테고리의 다른 글
[Java] 다형성(Polymorphism) (0) | 2022.09.14 |
---|---|
[네트워크][HTTP]에러코드 (0) | 2022.09.14 |
[Java]캡슐화(Encapsulation) (0) | 2022.09.13 |
[Java]기초 (0) | 2022.09.13 |
[Java]상속(Inheritance) (0) | 2022.09.13 |