Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- AI
- lambda
- AWS
- Java
- 홈서버
- 오픈소스
- class
- optional
- Kotlin
- bluegreen
- Claude
- FCM
- 무중단배포
- gemini cli
- S3
- Interface
- WebFlux
- 오픈소스 기여
- n8n
- Quarkus
- http-only cookie
- 자동화
- GEMINI
- functional interface
- Security
- Workflow
- spring boot
- firebase
- coroutine
Archives
- Today
- Total
빠르게 학습하고 빠르게 적용하자
자바 개념 정복하기 - Optional/Lambda편 본문
자바 개념을 확실히 다잡고 진짜 제대로 알고쓰자는 의미에서 기록을 시작합니다.
내용은 학교 수업시간에 배운 내용을 바탕으로 저의 추가 지식을 더하고 검색을 통해 작성했습니다.
목차 (배운 내용)
- 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에 함수형 프로그래밍 패러다임이 통합된 방식 이해에 큰 도움을 얻음.