SEB_BE_43 / 23.01.04 회고

rse·2023년 1월 9일
0

코드스테이츠_BE_43

목록 보기
11/65

핵심

  • 열거형
  • 제네릭
  • 예외 처리
  • 컬렉션 프레임워크

열거형 (Enum)

상수를 모아놓은 것.

  • 여러 상수들을 보다 편리하게 선언하고 관리할 수 있게함.

  • 상수명의 중복을 피하고, 타입에 대한 안정성을 보장.

  • 같은 효과를 낼 수 있는 다른 코드에 반해 훨씬 더 간결하고 가독성이 좋은 코드를 작성할 수 있으며 switch문에서도 작동이 가능하다.

  • 상수는 대문자로, 공백은 언더바로 표시. 그것이 관례라고 한다.

enum을 사용해서 선언해주며 변수명 {상수들} 이렇게 사용.

위 사진 출력값은 봄

enum을 활용하면 이렇게 쓸 수 있다.
enum에서 사용할 수 있는 메서드가 있으니 외우지 말고 쓸 때마다 찾아서 익숙해 질 수 있게 하자.


제네릭

제네릭이란?


만약 다 다른 타입의 객체를 만들고자한다면 이런식으로 하나하나 지정해줘야 할 것이다.

하지만 제네릭을 쓴다면 타입을 나중에 정의해줘도 된다.

이런식으로.

제네릭을 쓰는 방법은 class 클래스 명 < T > 이렇게 사용가능하다.
< > 괄호 안에는 무슨 알파벳이 들어가도 상관은 없으나 통상적으로 T는 Type 으로 T를 많이 쓴다고 한다.
제네릭이란 타입을 추후에 지정할 수 있게 일반화 해둔 것. 이라고 말한다. 작성한 클래스 또는 메서드의 코드가 특정 데이터 타입에 얽매이지 않게 해둔 것을 의미

제한된 제네릭 클래스

제네릭 클래스는 제한도 걸 수 있다.

이런식으로 Basket class를 보면 < T extends Flower > 이라고 적혀있다. 이건 인스턴스화 할 때 Flower 하위 클래스만 지정하도록 제한된 것.

와일드 카드

의미

어떠한 타입으로든 대체될 수 있는 타입 파라미터

<? extends T>
<? super T> 

이렇게 사용할 수 있다.



User < ? extends Phone> user 는 Phone과 그 하위 클래스 타입을 말한다. 그러므로 Iphone, Galaxy 모두 가능.

< ? extends는 상위 제한을 두는 것.

User < ? super Galaxy> user 는 Galaxy와 상위 클래스 타입을 한다.
따라서 Galaxy, Phone이 해당되겠다.

< ? super는 하위 제한을 둔다.


예외 처리

컴파일 에러 / 런타임 에러

  • 컴파일 에러
    컴파일 에러는 자바 컴파일러가 오류를 감지하여, 사용자에게 친절하게 알려주기 때문에 상대적으로 쉽게 발견하고 수정할 수 있다.
  • 런타임 에러
    코드를 실행하는 과정, 즉 런타임 시에 발생하는 에러를 가리킵니다. 즉, 프로그램이 실행될 때 만나게되는 에러

에러와 예외의 차이

에러란 한번 발생하면 복구하기 어려운 수준의 심각한 오류를 의미하고, 대표적으로 메모리 부족(OutOfMemoryError)와
스택오버플로우(StackOverflowError) 등이 있다.

반면 예외는 잘못된 사용 또는 코딩으로 인한 상대적으로 미약한 수준의 오류로서 코드 수정 등을 통해 수습이 가능한 오류를 지칭한다.

try / catch

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

예외가 발생할 것 같다고 생각하는 부분을 try문에 넣고,
만약 예외가 발생한다면 실행시킬 catch문을 작성한다.
catch문 뒤에 ( ) 안에 들어가는 것은 에러 메세지다. 에러메세지를 담고 있는 e1 이라는 변수? 이름 이다. 만약 어떤 에러인지 모르겠다면 Exception 을 넣고 실행시켜보자. Exception은 모든 에러의 상위 클래스로 무조건 실행된다고 보면 된다.

public class RuntimeExceptionTest {

    public static void main(String[] args) {

        try {
            System.out.println("[소문자 알파벳을 대문자로 출력하는 프로그램]");
            printMyName(null); // (1) 예외 발생
            printMyName("abc"); // 이 코드는 실행되지 않고 catch 문으로 이동
        } 
        catch (ArithmeticException e) {
            System.out.println("ArithmeticException 발생!"); // (2) 첫 번째 catch문
        } 
        catch (NullPointerException e) { // (3) 두 번째 catch문
            System.out.println("NullPointerException 발생!"); 
            System.out.println("e.getMessage: " + e.getMessage()); // (4) 예외 정보를 얻는 방법 - 1
            System.out.println("e.toString: " + e.toString()); // (4) 예외 정보를 얻는 방법 - 2
            e.printStackTrace(); // (4) 예외 정보를 얻는 방법 - 3
        } 
        finally {
            System.out.println("[프로그램 종료]"); // (5) finally문
        }
    }

    static void printMyName(String str) {
        String upperCaseAlphabet = str.toUpperCase();
        System.out.println(upperCaseAlphabet);
    }
}

여기서
e.getMessage() = 에러 원인을 간단하게 보여줌.
e.toString() = 에러의 Exception 내용과 원인을 출력.
e.printStackTrace() = 에러의 발생근원지를 찾아서 단계별로 에러 출력.


컬렉션 프레임워크

컬렉션이란 여러 데이터들의 집합을 의미
편리한 메서드들을 미리 정의해놓은 것을 컬렉션 프레임워크
특정 자료 구조에 데이터를 추가하고, 삭제하고, 수정하고, 검색하는 등의 동작을 수행하는 편리한 메서드들을 제공해준다.

  • List
    List는 데이터의 순서가 유지되며, 중복 저장이 가능한 컬렉션을 구현하는 데에 사용됩니다.

ArrayList, Vector, Stack, LinkedList 등이 List 인터페이스를 구현합니다.

  • Set
    Set은 데이터의 순서가 유지되지 않으며, 중복 저장이 불가능한 컬렉션을 구현하는 데에 사용됩니다.

HashSet, TreeSet 등이 Set 인터페이스를 구현합니다.

  • Map
    Map은 키(key)와 값(value)의 쌍으로 데이터를 저장하는 컬렉션을 구현하는 데에 사용됩니다.

데이터의 순서가 유지되지 않으며, 키는 값을 식별하기 위해 사용되므로 중복 저장이 불가능하지만, 값은 중복 저장이 가능합니다.

HashMap, HashTable, TreeMap, Properties 등

List

  • 배열처럼 일렬로 늘어놓은 구조
  • 객체를 저장하면 자동으로 인덱스 부여. 인덱스로 검색, 추가, 삭제 가능
  • 중복 가능, 순서 유지.

Array List

저장하면 이런식으로 저장됨.

검색하기 좋은 구조, 첫번째 or 마지막 추가, 삭제, 검색 용이.

하지만 중간에 작업을 해야할 경우 뒤에 인덱스들이 1칸씩 당겨지거나 밀려야하니 시간이 걸림.
ex ) 1번 인덱스 뒤에 새로운 인덱스 추가한다면 2,3이 한칸씩 뒤로 가야함.

Linked List

서로 붙어서 저장 안됨.
데이터를 효율적으로 사용가능.
중간에 추가, 삭제 용이.
검색은 한개 한개 봐야하기에 속도 느림.

iterator

컬렉션에 저장된 요소를 순차적으로 읽는다.
hasNext() : 다음에 읽어올 요소가 있는지 확인 true : false
next() : 요소를 읽어온다.
remove() : 삭제한다. next를 사용하고 remove를 사용해야 함.

ArrayList<String> list = ...;
Iterator<String> iterator = list.iterator();

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

Set

  • 순서 유지 X / 중복 X

Hash set

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("Java"); // 중복

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

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

출력결과는 Java, Python 두개만 들어있는 것을 알 수 있다.

Tree set

Tree set은 나무를 뒤집어 놓은 모습이라고 생각하면 될 것 같다.

Tree set의 왼쪽은 작은 수 오른쪽은 큰 수라고 생각하면 편하다.

그림을 그리면 이렇게 된다.

요소보다 큰 것은 오른쪽 , 작은 것은 왼쪽으로 형성이 된다.

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");

        System.out.println(workers);
        System.out.println(workers.first());
        System.out.println(workers.last());
        System.out.println(workers.higher("Lee"));
        System.out.println(workers.subSet("Kim", "Park"));
    }
}

이렇게 정렬이 되어서 출력이 되는 걸 확인할 수 있다.

Map

key와 value로 묶여서 저장한다. 이걸 Entry라고 한다.

  • 순서 저장 안됨, key중복 안됨, value 중복 가능.
import java.util.*;

public class HashMapExample {
    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();
    }
}


연습문제

Integer 타입의 ArrayList를 입력받아 모든 요소를 더한 값을 리턴해야 합니다.

import java.util.*;

public class Solution { 
  public int sumAllElements(ArrayList<Integer> arrayList) {
    //TODO..
    int sum = 0;
    Iterator<Integer> result = arrayList.iterator();
     while (result.hasNext()) {
       Integer next = result.next();
       sum += next;
     }return sum;
  }
}

<String, Integer> 타입을 요소로 가지는 HashMap과 문자열을 입력받아, HashMap에 문자열을 key로 한 Entry가 있는지의 여부를 리턴해야 합니다.

import java.util.*;

public class Solution { 
  public HashMap<String, String> addFullNameEntry(HashMap<String, String> hashMap) {
    //TODO..
      HashMap<String, String> fullName = hashMap.entry;
        
  }
}
profile
기록을 합시다

0개의 댓글