Notice
Recent Posts
Recent Comments
Link
«   2026/06   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Archives
Today
Total
관리 메뉴

빠르게 학습하고 빠르게 적용하자

자바 개념 정복하기 - Optional/Lambda편 본문

카테고리 없음

자바 개념 정복하기 - Optional/Lambda편

osoohynn 2025. 9. 6. 15:11

자바 개념을 확실히 다잡고 진짜 제대로 알고쓰자는 의미에서 기록을 시작합니다.

내용은 학교 수업시간에 배운 내용을 바탕으로 저의 추가 지식을 더하고 검색을 통해 작성했습니다.

목차 (배운 내용)

  • Optional 정의
  • Optional 사용 예제
  • Lambda 사용 예제
  • 함수형 인터페이스
  • 참조 메서드

Optional - Null 안정성 확보

Optional(옵셔널)

자바에서 흔히 발생하는 NullPointerException을 줄이기 위해 만들어진 클래스.
값이 있을 수도, 없을 수도 있는 객체를 감싸는 래퍼(Wrapper) 역할을 함.

  • Optional이란?
    • T 타입 객체를 감싸는 클래스
    • null 안정성을 제공 (안전한 null 처리)
    • 마치 값을 담는 상자(Box) 같은 개념
// 값이 있을 때
Optional<String> opt1 = Optional.of("Hello");

// 값이 없을 수도 있을 때
Optional<String> opt2 = Optional.ofNullable(null);

// 아예 빈 값
Optional<String> opt3 = Optional.empty();
Optional<String> opt = Optional.of("Java");

// 1) 값 직접 꺼내기
System.out.println(opt.get()); // "Java" (값 없으면 예외 발생)

// 2) 값이 있으면 꺼내고, 없으면 기본값
System.out.println(opt.orElse("기본값"));

// 3) 값이 있으면 실행하기
opt.ifPresent(v -> System.out.println("길이: " + v.length()));
 
  • 주요 메서드
    • Optional.of(value): null이 아닌 값을 감쌈
    • Optional.ofNullable(value): null일 수도 있는 값을 감쌈
    • isPresent(): 값 존재 여부 확인
    • ifPresent(consumer): 값이 존재할 경우 동작 수행
    • orElse(defaultValue): 값 없을 경우 기본값 반환
    • get(): 값 직접 반환 (없으면 예외 발생)

Lambda - 간결한 코드 작성

💡 Lambda Expression (람다식)

함수를 간단한 식(Expression) 으로 표현하는 방법.
이름이 없는 함수 → 익명 함수(Anonymous Function).
간결하게 코드를 작성하고 함수형 프로그래밍을 지원.


함수형 인터페이스 (Functional Interface)

  • 람다식이 구현할 수 있는 대상
  • 추상 메서드가 하나만 있는 인터페이스
  • @FunctionalInterface 어노테이션으로 명시 가능

자바 제공 주요 함수형 인터페이스 (java.util.function):

인터페이스설명
Runnable 매개변수 없음, 반환값 없음
Supplier<T> 매개변수 없음, 반환값 T
Consumer<T> 매개변수 T, 반환값 없음
Function<T, R> 매개변수 T, 반환값 R
BiConsumer<T, U> 매개변수 T, U, 반환값 없음
BiFunction<T, U, R> 매개변수 T, U, 반환값 R

기본 문법

 
(매개변수) -> { 실행문 }
  • 매개변수가 1개 → 괄호 생략 가능
  • 실행문이 한 줄 → {}와 return 생략 가능
// 람다식
Calculator calculator1 = (int a, int b) -> { return a + b; };

// 더 간결하게
Calculator calculator2 = (a, b) -> a + b;

// 함수형 인터페이스
@FunctionalInterface interface Calculator {
	int calculate(int a, int b); 
}

메서드 참조 (Method Reference)

💡 메서드 참조

하나의 메서드만 호출하는 람다식 → 더 간결하게 표현 가능.

종류람다식메서드 참조
static 메서드 참조 (x) → ClassName.method(x) ClassName::method
인스턴스 메서드 참조 (obj, x) → obj.method(x) ClassName::method
특정 객체 메서드 참조 (x) → obj.method(x) obj::method
// static 메서드 참조
result.ifPresent(System.out::println);

// 인스턴스 메서드 참조
MyFunction myFunction1 = String::equals;

// 특정 객체 메서드 참조
String s = "Java";
MyFunction myFunction2 = s::equals;

핵심 실습 코드

함수형 인터페이스 & 람다식

@FunctionalInterface interface Calculator {
	int calculate(int a, int b);
}

public class Main {
    public static void main(String[] args) {
        // 익명 클래스 
        Calculator calculator = new Calculator() { 
            public int calculate(int a, int b) {
                return a + b;
            } 
        }; 

        // 람다식 
        Calculator calculator1 = (int a, int b) -> { return a + b; };

        // 더 간결하게
        Calculator calculator2 = (a, b) -> a + b; 
    }
}

자바 기본 제공 함수형 인터페이스

import java.util.function.Supplier;

public class D {
    Calculator add = (a, b) -> a + b;

    public static void main(String[] args) {
    	test((a, b) -> a + b);
    }

    public static void test(Calculator calculator) {
        int result = calculator.calculate(1, 2);
        System.out.println(result);
        Supplier<Integer> s = () -> 1;
    } 

    public static Calculator calculate() {
    	return (a, b) -> a + b;
    }
}

메서드 참조 & Optional

import java.util.Optional;

@FunctionalInterface
interface MyFunction {
	boolean method(String s);
}

class MyClass {
    String name;
    
    public MyClass(String name) {
    	this.name = name;
    } 

    public boolean eqName(String name) {
    	return this.name.equals(name);
    }
} 

public class E {
    public static void main(String[] args) {
        MyClass myClass = new MyClass("Java");
        
        MyFunction myFunction = myClass::eqName;
        
        Optional<String> result = Optional.ofNullable("Java");
        result.ifPresent(System.out::println);
        
        Optional<Integer> result2 = result.map(String::length);
        result2.ifPresent(System.out::println);
    } 
}

트러블 슈팅

  • Optional 1: get()을 바로 사용해 예외 발생 → orElse, ifPresent 사용
  • Optional 2: orElse()는 항상 실행, orElseGet()은 필요할 때만 실행 → 비용 큰 연산 시 orElseGet() 권장
  • Lambda 1: 람다식 타입 추론 오류 → 함수형 인터페이스 타입을 명확히 지정 필요

 

배운 점

  • Null 안정성의 중요성
    • Optional 활용으로 NullPointerException 방지 가능
  • 함수형 프로그래밍의 이점
    • 람다식으로 간결하고 가독성 높은 코드 작성 가능
    • 함수형 인터페이스(Function, Consumer, Supplier 등) 활용법 학습
    • 메서드 참조(::)를 통한 더 간결한 표현 가능

➡ 이를 통해 더 모던하고 안전한 Java 코드 작성 가능.
특히, Java에 함수형 프로그래밍 패러다임이 통합된 방식 이해에 큰 도움을 얻음.