Programming-[Backend]/Java

자바 기초 강의 정리 - 2. 컬렉션, 함수형 인터페이스, 에러와 예외

컴퓨터 탐험가 찰리 2024. 6. 6. 20:58
728x90
반응형

인프런 얄코의 제대로 파는 자바 강의를 듣고 정리한 내용이다.

 

중요하거나 실무를 하면서 놓치고 있었던 부분들 위주로만 요약 정리한다.

자세한 내용은 강의를 직접 수강하는 것이 좋다.

https://www.inflearn.com/course/%EC%A0%9C%EB%8C%80%EB%A1%9C-%ED%8C%8C%EB%8A%94-%EC%9E%90%EB%B0%94/dashboard

 

 


 

 

1. 컬렉션

 

 

List

LinkedList

스택과 큐는 예전에는 따로 자료구조로 사용하였으나, 현재는 LinkedList 하나로만 사용한다.

 

ArrayList vs LnikedList

주로 ArrayList를 많이 쓰지만, 장단점에 대해 잘 기억하고 써야한다. ArrayList는 각 요소들로의 접근이 빠르지만 추가 |  제거 시에는 성능에 부하를 주고 메모리를 더 차지할 수 있다. 추가 | 제거가 많이 일어나는 경우를 다룬다면 LinkedList를 사용해야함을 잊지말자

 

 

Set

 

HashSet, LinkedHashSet

LinkedHashSet은 넣는 순서대로, HashSet은 마치 정렬된 것 같지만 실제로는 정렬을 보장하지 않는 형태로 저장된다.

 

TreeSet

Red-Black 트리로 자료를 저장한다. 따라서 정렬이 되는 형태이며 조회는 빠를 수 있으나 삽입 | 삭제는 느리다. 그리고 정렬 기준이 있는 데이터를 넣어야만한다. Comparator로 구현하지 않는 클래스의 인스턴스는 TreeSet에 중복으로 삽입할 수 없다. 비교가 필요하면 생성자 등에 Comparator를 구현해야한다.

 

	// TreeSet의 생성자 인자로 Comparator를 구현한 Sorter 주입
    TreeSet<Airplane> airplaneTreeSet = new TreeSet<>(new AirplaneSorter());

    //Comparator를 구현
    public class AirplaneSorter implements Comparator<Airplane> {
        @Override
        public int compare(Airplane o1, Airplane o2) {
            var result = getClassPoint(o2) - getClassPoint(o1);

            if(result == 0) {
                result = o1.hashCode() - o2.hashcode();
            }

            return result;
        }
    }
	
    // Airplane 객체의 이름값의 첫 글자를 숫자로 반환하여 크기로 비교할 수 있도록함
    // 뭔가 로직을 만든다는 예시일 뿐이고, 실제로 문자열 값으로 비교하고 싶을땐 compareTo() 메서드를 사용할 수 있음
    public int getClassPoint(Airplane a) {
        int result = Integer.valueOf(a.getName().charAt(0));
        //.. 기타 로직
        return result;
    }

 

 

 

이터레이터

 

순회 중간에 전체 컬렉션의 개수를 변경하는 작업이 필요하다면 for문은 불가하고 iterator를 사용해야한다.

// 컬렉션의 내부 요소 삭제
while (testIter.hasNext()) {
        if(testIter.next() % 2 == 0) {
            testIter.remove();
        }
    }
    
// 오류 발생
for(Integer num: testHashSet) {
    if(num % 2 == 0) testHashSet.remove(num);
}

 

 

 

2. 함수형 인터페이스

 

@FunctionalInterface 

함수형 인터페이스는 interface 위에 작성하며 1개의 메서드만 추가할 수 있다. 특정 기능을 갖는 함수만 만드는 것이다.

 

java.util.function

자주 사용하는 인터페이스를 미리 정의해놓은 패키지이다. 여기서 제공하는 함수형 인터페이스들은 다음과 같다. Operator는 인자와 반환값의 타입이 같은 형태를 뜻한다.

함수형 인터페이스 메서드 인자 타입 반환값 타입
Runnable run    
Supplier<T> get   T
Consumer<T> accept T  
BiConsumer<T, U> accept T, U  
Function<T, R> apply T R
BiFunction<T, U, R> apply T, U R
Predicate<T> test T boolean
BiPredicate<T, U> test T, U boolean
UnaryOperator<T> apply T T
BinaryOperator<T> apply T, T T

 

 

 

 

3. 에러와 예외

 

Error & Exception

Error, Exception 모두 Throwable의 자식 클래스이다. 그리고 둘 다 RuntimeException이다. CompileException과는 다르게 프로그램이 실행 중일 때 일어나는 에러를 뜻한다. RuntimeException은 개발자의 로직 실수에 의해 발생할 수 있으므로 컴파일 때 반드시는 잡지 않는 UncheckedException이다. 컴파일 단계에서 에러가 나는 에러는 컴파일러가 잡아주고 프로그램 실행 전에 반드시 잡아야하는 CheckedException이다.

 

에러는 무한 루프, 메모리 한도 초과 등 해결이 불가능한 문제이다. 보통 시스템 레벨의 문제이다.

예외는 파일이 없음, iterable의 index 초과 등 개발자가 대비하면 해결할 수 있는 문제들이다.

 

예외 던지기

try-catch 문으로 메서드 내에서 에러를 처리하면 메서드를 실행하다가 에러가 나는 경우 해당 메서드 내에서 exception이 발생한다. 그렇게 하지 않고 method 수준에서 throws를 정의하면 해당 메서드를 호출한 부분에서 try-catch 문으로 에러를 처리해줘야한다.

 

// 메서드 내부에서 try-catch 처리하는 경우
    public float divider1(int num, int divider) {
        try {
            if (divider < 0) {
                throw new RuntimeException("divider는 0보다 커야합니다.");
            } else {
                return (float) num / divider;
            }
        } catch (ArithmeticException e) {
            System.out.println(e.getMessage());
        }
    }
    
    // 메서드 외부로 try-catch 처리의 책임을 넘기는 경우
    public float divider2(int num, int divider) throws ArithmeticException{
        if (divider < 0) {
            throw new RuntimeException("divider는 0보다 커야합니다.");
        } else {
            return (float) num / divider;
        }
    }

 

 

메서드 내부에서 try-catch로 처리하고, 외부로도 throws를 통해 에러를 전파할 수도 있다.

 

 

try-with-resources

파일 등을 열고 처리한 뒤 파일을 닫아줘야할 때 자동으로 닫히도록 하는 문법이다. try문 뒤의 괄호 안에 자원의 초기화문을 적어주면 된다.

try (SomeFile sf = new SomeFile()) {
	//...로직 수행
} catch (SomeException e) {
	//...e.printStackTrace();
}

 

이것은 해당 자원을 사용하는 클래스가 AutoClosable 클래스를 implements 할때 가능하다.

 

 

 

728x90
반응형