추석이 끝났다.
추석에는 코드스테이츠도 교육을 안하기 때문에
따로 TIL을 작성하진 않았다.
연휴가 길어져서그런지 너무나도 게을러져버린 나…

image

그래도 하루에 1일1커밋을 지키려고
알고리즘문제를 3~5개정도 매일 풀었다.
추석도 끝났으니 오늘부터 다시 열심히 시작해보자!!


저번주에는 자바의 핵심인 객체지향 심화공부와
핵심요소인 4대원칙을 적용한 코드에 대해
공부를 해보았다. 오늘의 주를 이룰 공부는
자바의 컬렉션과 열겨형,제너릭,예외처리에 대해 공부해볼 예정이다.
들어가기 앞서서 열겨형,제너릭,예외처리는 어느정도
공부를 해둔상태라 알고는 있지만 조금 더 개념을 잡아가보도록 하자!

열거형(Enum)

열거형이란? 간단하게 정의하자면
서로 연관된 상수들의 집합__이다.
이러한 상수들을 보다 간편하게 관리할 때 유용하게 사용할 수 있는
자바의 문법 요소이고, 몇 가지로 한정된 변하지 않는 데이터를 다르는데 사용한다.
*JDK 1.5이전 버전에서는 enum 지원x

열거형 사용법

enum 열거형이름 { 상수명1, 상수명2, ... }

열거형을 사용할땐 위와 같이 작성한다.
관례적으로 대문자로 작성한다.
예를들어 사계절을 열겨형으로 나눈다는 예제를 가정하면

enum Seasons { 
    SPRING, //정수값 0 할당
    SUMMER,  //정수값 1 할당
    FALL, //정수값 2 할당
    WINTER //정수값 3 할당
}

자동적으로 시작부터 0인 정수값으로 할당되어 상수를 가르킨다.
열거형을 접근하는 방법은 static 변수를 참조하는 것과 동일하다.

Seasons.SPRING

static 변수 접근 방법은 클래스이름.변수 였는데
열거형 접근 방법은 열거형이름.상수명이다.

열거형 사용예제

enum Seasons {SPRING, SUMMER, FALL, WINTER}

public class Main {
    public static void main(String[] args) {
        Seasons seasons = Seasons.SPRING;
        switch (seasons) {
            case SPRING:
                System.out.println("봄");
                break;
            case SUMMER:
                System.out.println("여름");
                break;
            case FALL:
                System.out.println("가을");
                break;
            case WINTER:
                System.out.println("겨울");
                break;
        }
    }
}
// 출력 : 봄

Seasons이라는 열거형이름으로 상수값 4개를 할당했다.
Seasons타입으로 seasons라는 참조변수에 Seasons.SPRING을 할당했다.
switch case문은 char, byte, short, int, Character, Byte, Short, Integer, String, enum 타입 사용이
가능하기 때문에 enum으로 사용자 지정된 객체 seasons을 사용해도 동작이 가능하다.

이와 같이 열겨형의 사용자 타입으로
선언된 객체에 대해 여러가지 기능들을 사용할 수 있다.

메서드 리턴타입 설명
name() String 열겨 객체가 가지고 있는 문자열을 리턴, 리턴되는 문자열은 열거타입을 정의할 때 사용한 상수 이름과 동일하다.
ordinal() int 열겨 객채의 순번(0번부터)을 리턴
compareTo(비교값) int 주어진 매개값과 비교해서 순번 차이를 리턴
valueOf(String name) 열거 타입 주어진 문자열의 열거 객체를 리턴
values() 열거 배열 모든 열거 객체들을 배열로 리턴


제너릭(Generic)

제너릭은 한개의 클래스의 여러가지 타입의 데이터를
저장할 수 있는 인스턴스를 만들게해주는 문법이라 볼 수 있다.
<T>를 타입 매개변수라고 한다.

클래스 이름 옆에 작성해줌으로써 클래스 내부에서
사용할 타입 매개변수를 선언할 수 있다.

코드로 예제를 들어보자.

public class Main {
    public static void main(String[] args) {
        GenericEx<String> people1 = new GenericEx<>("철수");
        GenericEx<Integer> people2 = new GenericEx<>(1);
        System.out.println(people1.getName());
        System.out.println(people2.getName());
    }
}

class GenericEx<T> {
    private T name;

    public GenericEx(T name) {
        this.name = name;
    }

    public T getName() {
        return name;
    }

    public void setName(T name) {
        this.name = name;
    }
}
//출력
철수
1

GenericEx라는 클래스의 name라는 인스턴스변수는
어떤 타입을 받을지 모르자고 가정해보자
String, Integer 등… 여러가지 타입을 받을 수 있는 변수인데
만약 제너릭이 없다면 우리는 여러 클래스를 만들어
String name , int name 따로 선언을 해주어야한다.

하지만 제너릭 문법을 이용하면
위와 같이 하나의 클래스로 name이라는 변수에
여러가지 타입의 데이터를 담을 수 있는 것이다.


타입 매개변수 여러개 사용

class GenericEx<K, V> { ... }

타입 매개변수는 임의의 문자로 지정이 가능하다.

T : Type
K : Key
V : Value
E : Element
N : Number
R : Result

의 첫 글자를 따온 것이다.


제너릭 클래스 정의시 주의할 점

class GenericEx<T> {
	private T name1; // O 
	static T name2; // X 
}

위의 예제와 같이 클래스 변수, 즉 static으로 선언된 변수는 사용할 수 없다.
그 이유는 클래스 변수에 타입 매개변수를 사용할 수 있다면
클래스 변수의 타입의 인스턴스 별로 가지게 된다.
즉, name2라는 값을 사용하기위해

GenericEx<String> = new GenericEx<>("철수");
GenericEx<Integer> = new GenericEx<>(1);

각각 새로운 인스턴스를 선언했을때
클래스 변수는 공유변수이기때문에 타입이 달라져 사용할 수가 없는 것이다.


제너릭 메서드

제너릭을 클래스 전체에 선언할 수 있지만
클래스 내부의 특정 메서드만 제네릭으로 선언할 수도 있다.
이를 제네릭 메서드라고한다.

class Basket<T> {                        // 1 : 여기에서 선언한 타입 매개변수 T와 
		...
		public <T> void add(T element) { // 2 : 여기에서 선언한 타입 매개변수 T는 서로 다른 것입니다.
				...
		}
}
Basket<String> basket = new Bakset<>(); // 위 예제의 1의 T가 String으로 지정됩니다. 
basket.<Integer>add(10);                // 위 예제의 2의 T가 Integer로 지정됩니다. 
basket.add(10);                         // 타입 지정을 생략할 수도 있습니다. 

위와 같이 선언하고 호출할 수 있다.
제네릭 메서드는 클래스 타입 매개변수와 달리 static메서드에서도 선언하여 사용할 수 있다.


와일드 카드

와일드 카드는 어떠한 용도로든 사용될 수 있는 일종의 비장의 카드란 의미다.
자바의 제네릭에서 와일드카드는 “어떠한 타입으로든 대체될 수 있는” 타입 파라미터를
의미하고, 기호로 ”?” 로 사용한다.

사용방법

<? extends T>
<? super T>

T는 앞서 얘기한 타입매개 변수이고 저라리에는
다른 타입의 값들도 들어갈 수 있다.

<? extends T> : 상한에 제한을 두는것
-> T와 T를 상속받은 하위 클래스 타입만 타입 파라미터로 받을 수 있도록 지정

<? super T> : 하한에 제한을 두는 것
-> T와 T의 상위 클래스만 타입 파라미터로 받을 수 있도록 지정

extends와 super를 조합하지 않은 <?> 와일드 카드는
<? extends Object>와 같은 표현이다.


예외 처리(Exception Handling)

특정 원인에 의해서 발생한 에러에 대응할 수 있는 코드를 미리 사전에
작성하여 프로그램의 비정상적인 종료를 방지하고, 정상적인 실행 상태를
유지하기 위해 자바 문법에서는 예외처리가 필요하다.

대표적인 예외 케이스

  1. 사용자 입력 오류
  2. 네트워크 연결 끊김
  3. 디스크 메모리 공간 부족 등 물리적 한계
  4. 개발자의 코드 에러
  5. 존재하지 않는 파일 불러오기

에러(error)와 예외(exception)는 다른 말이다.
에러는 복구하기 어려운 수준의 심각한 오류이다.
예를 들어 메모리 부족(OutOfMemoryError)과
스택오버플로우(StackOverflowError) 등이있다.
반면, 예외는 코딩으로 인한 상대적으로 미약한 수준의 오류다.


컴파일 에러

이름과 같이 컴파일 할 때 발생하는 에러다.
주로 세미콜론생략, 오탈자, 잘못된 자료형, 잘못된 포맷 등
문법적인 문제를 가르키는 신택시(syntax)오류류로부터 발생해
신택스 에러(Systax Errors)라고 부른다.

코드로 오류를 보자

public class Main {
    public static void main(String[] args) {
        int i = 1;
        System.out.println(1)
    }
}

System.out.println 뒤에 세미콜린이 안붙어있다.
실행하게되면 error: ';' expected
이렇게 Syntax 오류가 발생하게 된다.
컴파일 에러는 컴파일러에 의해 발견된다.


런타임 에러

런타임 에러는 실행도중 발생하는 에러를 가르킨다.
코드로 예제를 보자.

public class Main {
    public static void main(String[] args) {
        String[] strs = {"a","b","c"};
        System.out.println(strs[3]);
    }
}

간단하게 배열을 만들어 출력하는 프로그램이다
총 3개의 방에 각각 값들을 초기화 시켜주었고
[3]방을 출력하는 프로그램이다.
여기서 문제는 3번째 방은 초기화되어있지 않기때문에
ArrayIndexOutOfBoundsException와 같은 런타임 에러가 발생한다.
런타임 에러는 프로그램이 실행될 때에 JVM(자바 가상머신)에 의해 감지된다.


예외 클래스의 상속 계층도

image

예외 클래스의 상속 계층도이다.
java.lang -> Object -> Throwable 에서 에러와 예외로 나누어진다.
Throwable 클래스로 부터 확장되며, 모든 예외는 Exception 클래스이다.
Exception 클래스는 실행 예외 클래스(RuntimeException)와

일반 예외 클래스로 나눠질 수 있다.

실행 예외 클래스(Runtime Exception)
런타임 시 발생하는 Runtime Exception 클래스와 그 하위 클래스를 지칭한다.
컴파일러가 예외 처리 코드 여부를 검사하지 않는다는 의미에서
Unchecked Exception라고 부른다.
주로 개발자의 실수로 의해 발생하고 문법 요소가 관련되어있다.
ex) ClassCastException, ArrayIndexOutOfBoundsException, NullPorinterException …


일반 예외 클래스
Runtime Exception 클래스와 그 하위클래스를
제외한 모든 Exception 클래스와 하위 클래스를 가르킨다.
컴파일러가 코드 실행 전에 예외 처리 코드 여부를 검사한다고 하여
Checked Exception라 부른다.
주로 잘못된 클래스명이나 데이터 형식 등의 사용자편의 실수로 발생하는 경우가 많다.


try - catch

자바에서의 예외 처리하기위한 문법이다.
사용 방법은 아래와 같다

try {
    // 예외가 발생할 가능성이 있는 코드를 삽입
} 
catch (ExceptionType1 e1) {
    // ExceptionType1 유형의 예외 발생 시 실행할 코드
} 
catch (ExceptionType2 e2) {
    // ExceptionType2 유형의 예외 발생 시 실행할 코드
} 
finally {
    // finally 블럭은 옵셔널
    // 예외 발생 여부와 상관없이 항상 실행
}

간단하다. 예외가 발생할 것 같은 코드를
try 구문에 넣어 실행 시킨 후.
에러의 유형의 클래스를 catch구문에 입력하고 매개변수를 적어준다.
그리고 예외가 발생한 클래스와 일치할경우
catch 구문의 실행내용이 실행되면 finally 구문으로 넘어가며
프로그램은 멈추지않고 계속 진행된다.

코드 예제를 통해 사용해보자

public class Main {
    public static void main(String[] args) {
        String[] strs = {"a","b","c"};
        try {
            System.out.println(strs[3]);
        }catch (NullPointerException e1){
            System.out.println("NullPointerException 발생 !!");
        }catch (ArrayIndexOutOfBoundsException e2){
            System.out.println("ArrayIndexOutOfBoundsException 발생 !!");
        }finally {
            System.out.println("종료");
        }
    }
}

//출력
ArrayIndexOutOfBoundsException 발생 !!
종료

배열 범위를 넘어가는 간단한 예외처리를 해볼 것이다.
우선 e1, e2 매개변수에 각각 예외클래스를 지정해 주었다.
e1 첫번째는 NullPointerException
e2 두번째는 ArrayIndexOutOfBoundsException
배열 범위초과의 문제니 두번째에 해당하는 예외가 발생할 것이다.
그리고 마지막에는 finllay로 종료를 출력하게 적어두었다.

여기서 예외처리 케이스가 2가지가 있지만
해당되는 예외클래스의 구문만 실행된 모습이다!!
또한 finally는 Optional이므로 사용해도되고 안해도된다.


예외 전가

try-catch문 외에 예외를 호출한 곳으로 다시 예외를 떠넘기는 방법도 있다.

사용 방법

반환타입 메서드명(매개변수, ...) throws 예외클래스1, 예외클래스2, ... {
	...생략...
}

예외클래스를 지정해서 늘려가며 사용이가능하다.
특정 메서드에서 모든 종류의 메서드가 발생할 가능성이 있는 경우도 가능하다.

public void add() throws Exception{
	//실행 구문
}

Exception은 모든 예외의 상위 클래스이기 때문에
그 하위 클래스 타입의 예외 클래스들이 모두 포함되게 된다.
말그대로 예외 던지기이다.
예외를 발생하면 그 클래스로 던져버리는 것!
예외전가를 위한 코드 예제를 한가지보자

예외가 발생하지 않는 코드

public class ThrowExceptionTest {
    public static void main(String[] args) {
        try{
            System.out.println(1);
            throwException();
        }catch (ClassNotFoundException e){
            System.out.println(3);
            System.out.println(e.getMessage());
            System.out.println(4);
        }
        System.out.println(6);
    }

    static void throwException() throws ClassNotFoundException, NullPointerException{
        System.out.println(2);
        Class.forName("java.io.BufferedReader");
        System.out.println(5);
    }
}
//출력
1
2
5
6

흐름을 이해하기위해 프린트로 출력을 두었다.
메인 메소드에서 try구문을 실행하게되었다.
throwException(); 메소드를 실행하게되고
Class.forName으로 존재하는 클래스를 불러왔다.
당연히 BufferedReader라는 클래스는 아래와 같이 존재하기 때문에

image

예외가 발생하지 않아 1,2,5,6을 순서대로 출력한 모습이다.

예외가 발생하는 코드

public class ThrowExceptionTest {
    public static void main(String[] args) {
        try{
            System.out.println(1);
            throwException();
        }catch (ClassNotFoundException e){
            System.out.println(3);
            System.out.println(e.getMessage());
            System.out.println(4);
        }
        System.out.println(6);
    }

    static void throwException() throws ClassNotFoundException, NullPointerException{
        System.out.println(2);
        Class.forName("java.babo");
        System.out.println(5);
    }
}
// 출력
1
2
3
java.babo
4
6

이제 예외가 발생하는 위의 코드를 보자
존재하지않는 java.babo라는 임의의 클래스이름을 적었다.
당연히 예외가 발생하였고 throws로
throwExcetion(); 메소드를 호출한 main 메소드로 예외가 던져졌다.
catch문에 들어가 구문을 실행하여 메인메서드를 쭉 진행 한 모습을 볼 수 있다.
이처럼 예외처리 책임이 throwException 메소드가 아닌 main 메소드가 지게되었다.

이것을 예외 전가라고한다.


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

여러 데이터들을 그룹으로 묶어놓은 것.
컬렉션을 다루는 데에 있어 편리한 메소드들을 미리 정의해 놓은 것을
컬렉션 프레임워크라고 한다.

특정 자료 구조에 데이터를 추가하고,삭제,수정,검색 등 동작을 수행하는
편리한 메소드들을 제공해준다.

image
출처 - 컬렉션 자료구조 bahar-j님

주요 인터페이스로 List, Set, Map을 제공한다.
간단한 정의를 하면 아래와 같다.

List
-> 데이터의 순서가 유지되며, 중복 저장이 가능한 컬렉션을 구현하는데 사용
-> ArrayList, Vector,LinkedList 등이 List 인터페이스를 구현함.

Set
-> 데이터의 순서가 유지되지 않으며, 중복 저장이 불가능한 컬렉션을 구현하는데 사용
-> HashSet, TreeSet 등이 Set 인터페이스를 구현함

Map
-> 키(key)와 값(value)의 쌍으로 데이터를 저장한느 컬렉션을 구현하는데 사용된다.
-> 데이터의 순서가 유지되지 않으며, 키는 값을 식별하기 위해 사용되므로 중복 저장이 불가능하지만
중복 저장이 가능하다.


List<E>

중복사용 O / 저장 순서 O

배열과 같이 객체를 일렬로 늘어놓는 구조를 가지고 있다.
객체를 인덱스로 관리하기 때문에 객체를 저장하면 자동으로
인덱스가 부여되고, 인덱스로 객체를 검색,추가,삭제 등 여러 기능을 제공한다.
자세한 메소드들은 아래 공식문서 참조 (버전에따라 검색필요) [List (Java SE 11 & JDK 11 )]

ArrayList
List를 인터페이스로 구현한 클래스로
컬렉션 프레임워크에서 가장 많이 사용된다.
쉽게 생각하면 배열과 비슷한 형태라고 보면된다.
기능적으로는 Vector와 동일하지만 개선된 버전이므로 ArrayList를 더많이 사용한다.
배열은 생성될 때 크기를 고정되며, 크기 변경을 할 수없는데
ArraysList는 저장 용량을 초과하면 객체가 자동으로 저장용량이 늘어나게 된다.
(기존 길이의 1.5배만큼)

사용방법

List<타입 매개변수> 객체명 = new ArrayList<타입 매개변수>(초기 저장 용량);

여기서 타입 매개변수는 제너릭을 표기함을 의미한다.
초기 저장 용량은 지정하지 않으면 10으로 저장되어진다.

LinkedList
ArrayList와 동일하게 List를 인터페이스로 구현한 클래스이다.
ArraysList와 다른점은 데이터를 효율적으로 추가,삭제,변경할때 많이 사용한다.
배열에는 모든 데이터가 연속적으로 존재하는데
LinkedList에는 불연속적으로 존재하며, 이 데이터는 서로 연결(Link)되어 있다.

image
출처 - Programiz

위의 구조를 보면 각각 요소(node) Dog, Cat, Cow라는
요소들은 자신과 Next,Prev라는 주소값과 데이터로 구성되어 있다.
즉,Next와 Prev로 요소들을 참조하는 모습이다.

여기서 추가,삭제가 이루어 질 경우에
배열처럼 데이터를 복사할 필요없이 링크를 끊어준다고 생각하면 된다.


Iterator

번역 그대로하면 반복자라고한다.
컬렉션에 저장된 요소들을 순차적으로 읽어오는 역할을 한다.

메서드 설명
hasNext(); 읽어올 객체가 있으면 true, 없으면 false
next(); 컬렉션에서 하나의 객체를 읽어온다. hasNext()==true -> next();
remove(); next()를 통해 읽어온 객체를 삭제. next(); -> remove();

코드로 확인해보자

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class iteratorTest {

    public static void main(String[] args) {
        //list 객체 생성
        List<String> list = new LinkedList<>();

        //list 인덱스 추가
        list.add("A");
        list.add("B");
        list.add("C");
        System.out.println(list); // list .toString 출력 표시
        
        //List와 Set 인터페이스를 구현한 클래스들은 iterator 매소드 호출가능
        Iterator<String> iterator = list.iterator();
        System.out.println("------------------");
        while(iterator.hasNext()) {     // 읽어올 다음 객체가 있다면
            String str = iterator.next(); // next()를 통해 다음 객체를 읽어옵니다.
            System.out.println(str); // 뽑아온 객체 출력
            
            iterator.remove();; // next()를 통해 읽어온 객체 삭제
            System.out.println(list);
            System.out.println("------------------");
        }
    }
}

//출력
[A, B, C]
------------------
A
[B, C]
------------------
B
[C]
------------------
C
[]
------------------

LinkedList로 객체로 만들어진 list라는 인스턴스로
순차적으로 값을 뽑아내고 하나찍 제거하는 프로그램이다.


Set<E>

중복사용 X / 저장 순서 X
Set은 요소의 중복을 허용하지 않고, 저장 순서를 유지하지 않는 컬렉션이다.

HashSet
Set 인터페이스를 구현한 가장 대표적인 컬렉션 클래스이다.
Set 인터페이스 특성을 그대로 물려받으므로 중복된 값을 허용하지 않고,
저장 순서를 유지하지 않는다.

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"); // 중복 추가되지 않음.

    System.out.println(languages.toString()); 

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

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

//출력
[Java, C++, Javascript, Ruby, Python, Kotlin]
Java
C++
Javascript
Ruby
Python
Kotlin

선언 및 사용 방법은 List와 유사하다.
HashSet 객체로 languages 라는 인스턴스 생성
해당 인스턴스의 HasSet 메소드인 .add();를 이용해 값을 저장한다.

여기서 주의 깊게 봐야할 점은 Java라는 얘가
두번이나 .add되었지만 결과적으로는 하나만 저장된다는 사실과
위에서 부터 저장한 순서와 상관없이 저장이된다는 것이
List와 가장 큰차이점이라고 할 수 있다.

TreeSet
TreeSet은 이진트리형태로 데이터를 저장한다.
마찬가지로 Set 인터페이스 특성을 그대로 물려받으므로 중복된 값을 허용하지 않고,
저장 순서를 유지하지 않는다.

image

이진트리는 정렬과 검색에 특화된 자료 구조이다.
부모 노드와 자식 노드2개가 연결되있다.
왼쪽은 작은값, 오른쪽은 큰값 (ex 2,3 / 4,5…)
즉, 왼쪽 자식의 값이 루트나 부모보다 작고, 모든 오른쪽 자식의 값이
루트나 부모보다 큰값을 가지는 특징이 있다.

코드 예제로 확인해보자

public class TreeSetTeacher {
    public static void main(String[] args) {
        TreeSet<Integer> treeSet = new TreeSet<>();

        for (int i = 1; treeSet.size() < 6; i++) {
            int num = (int) (Math.random() * 45) + 1; // 난수발생. 1~45 숫자

            System.out.println(i + "번째 num = " + num);

            try { Thread.sleep(1000); } catch (Exception e) {} //쓰레드로 1초 딜레이주기

            treeSet.add(num);  // 추첨된 번호 추가하기
        }

        System.out.println("당첨 번호는 : " + treeSet);
    }
}
// 출력 - 할때마다 달라짐 (난수에의해)
당첨 번호는 : [12, 15, 16, 27, 30, 39]

위의 코드는 1~45값의 난수를 발생시켜 하나씩
TreeSet객체로 만들어진 인스턴에서 .add();하는 프로그램이다.
숫자가 뒤죽박죽 .add되어지는데 이진트리 구조에 의해
최종적으로 객체를 출력하게되면 정렬되서 나오는 모습을 볼 수 있다.
또한 중복된 난수가 확인되었을경우
저장을 하지않는 모습을 볼 수 있다.

Map<K,V>

Key는 중복 허용 X / Value는 중복 허용 O / 저장 순서 X
위에서 알아보았던, List,Set과는 다르게
Map은 키(Key)와 값(value)으로 구성된 객체를 저장하는 구조를 가지고 있다.
이 객체를 Entry객체라고한다. 이객체는 키와 값을 객체로 저장한다.

image

Map 인터페이스를 구현하는 클래스들도 많다.
HashMap, Hashtable, LinkedHashMap, Properties, TreeMap 등..

오늘은 HashMap만 우선 알아보자


HashMap

Map 인터페이스를 구현한 대표적인 클래스이다.
해시 함수를 통해 ‘키’와 ‘값이 저장되는 위치가 결정되고
사용자는 그 위치를 알 수 없고, 삽입되는 순서와 위치 또한 관계가 없다.
Map은 키와 값을 쌍으로 저장하기 때문에
iterator()를 직접 호출할 수 없다.

그 대신 keySet() 이나 entrySet() 메서드를 이용해 Set 형태로 반환된
컬렉션에 반복자를 통해 순회할 수 있다.

선언 방법

HashMap< 타입매개변수,  타입매개변수> hashmap = new HashMap<>();

다른 것들과 다른점은 키와 값의 타입매개변수
이렇게 두개를 설정해주어야한다.
아래의 코드로 간단하게 확인이 가능하다.

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());
    
}
//출력
 entry 수: 5

map.put()을 이용해 키와 값을 입력한다.
그리고 총 들어간 Entry의 개수를 int값을 반환해주는
size(); 확인시 5개가 저장된걸 볼 수 있다.

이와 같이 HashMap에 있는 메서드들로 여러가지 코드가 작성이 가능하다.



오늘은 대충알고 있던 내용들을 더욱 점검해보는 시간이였다.
아직 정확히 이해되진않았다. 여러번 타이핑해보면서
사용 방법에 익숙해져야할 것 같은 느낌이다.
머리속에 둥둥~ 다비슷해보이는 문법들이라 너무 헷갈리고
멘붕의 하루였다.. 아마 다른분들도 멘붕이겠지..?
그치만 새롭게 무언가 더 사용하는 방법을 익힌 것에
만족을하며 오늘 공부를 마친다!


오늘의 커피량: ☕️ ☕️ ☕️ ☕️️️️
오늘의 점심: 불고기, 계란말이, 공기밥