일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Elastic
- Elasticsearch
- 테슬라
- request cache
- redis
- ann
- vavr
- KNN
- API
- Docker
- Cache
- Selenium
- file download
- aggs
- Aggregation
- elasticsearch cache
- Query
- Analyzer
- NORI
- 양자컴퓨터
- java crawler
- TSLA
- api cache
- dbeaver
- 아이온큐
- IONQ
- aqqle
- JPA
- mysql
- java
- Today
- Total
아빠는 개발자
[java] 함수형 프로그래밍(Functional Programming) 은? 본문
Java에서 함수형 프로그래밍(Functional Programming)은 함수가 일급 시민(First-Class Citizen)으로 취급되고, 불변성(immutability)을 강조하며, 부작용(Side Effect)을 최소화하는 프로그래밍 패러다임입니다. Java 8에서 람다(Lambda)와 스트림(Stream) API가 도입되면서 함수형 프로그래밍을 더 쉽게 활용할 수 있게 되었습니다.
Java에서 이를 활용하는 방법
1. 람다 표현식 (Lambda Expression)
람다는 익명 함수(Anonymous Function)로, 메서드를 간결하게 표현할 수 있습니다. 주로 함수형 인터페이스(Functional Interface)를 구현할 때 사용됩니다.
// 기존 방식
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Hello, world!");
}
};
// 람다 표현식
Runnable runnableLambda = () -> System.out.println("Hello, world!");
}
함수형 인터페이스는 하나의 추상 메서드만 가지는 인터페이스입니다. @FunctionalInterface 어노테이션을 사용해 명시적으로 정의할 수 있습니다. 대표적인 예로 java.util.function 패키지에 있는 Function, Predicate, Consumer, Supplier 등이 있습니다.
@FunctionalInterface
interface MyFunction {
void execute();
}
3. 메서드 참조 (Method Reference)
메서드 참조는 기존 메서드를 람다처럼 사용할 수 있게 해줍니다.
// 람다 표현식
Function<String, Integer> func = s -> Integer.parseInt(s);
// 메서드 참조
Function<String, Integer> funcRef = Integer::parseInt;
스트림은 데이터의 흐름을 처리하는데 사용되며, 함수형 프로그래밍의 주요 개념 중 하나입니다. 컬렉션이나 배열 등의 데이터 소스를 필터링, 매핑, 축소(reduce) 등의 연산을 통해 처리할 수 있습니다.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 기존 방식
for (int i : numbers) {
if (i % 2 == 0) { System.out.println(i); }
}
// 함수형 방식
(Stream API) numbers.stream().filter(i -> i % 2 == 0) .forEach(System.out::println);
5. 고차 함수 (Higher-Order Function)
고차 함수는 함수를 인자로 받거나, 함수를 반환하는 함수입니다. Java에서는 람다와 메서드 참조를 사용해 고차 함수를 쉽게 구현할 수 있습니다.
// 함수를 인자로 받는 메서드
public static void applyFunction(Consumer<String> consumer) {
consumer.accept("Hello, Functional Programming!");
}
applyFunction(s ->System.out.println(s));
applyFunction(System.out::println);
6. 불변성 (Immutability)
함수형 프로그래밍에서는 상태 변화(즉, 값의 변경)를 피하는 것이 좋습니다. 불변 객체를 사용하고, 상태를 변경하지 않도록 코드를 작성하는 것이 핵심입니다.
// 불변 객체 예시
final String immutableString = "Hello";
7. 순수 함수 (Pure Function)
순수 함수는 동일한 입력에 대해 항상 동일한 출력을 반환하며, 함수 외부의 상태를 변경하지 않는 함수입니다.
public int add(int a, int b) {
return a + b; // 순수 함수
}
8. 함수 조합 (Function Composition)
함수를 결합하여 더 복잡한 기능을 수행할 수 있습니다. andThen, compose 메서드를 사용해 함수 조합을 쉽게 할 수 있습니다.
Function<Integer, Integer> multiplyByTwo = x -> x * 2;
Function<Integer, Integer> addThree = x -> x + 3;
Function<Integer, Integer> combinedFunction = multiplyByTwo.andThen(addThree);
System.out.println(combinedFunction.apply(5)); // 결과: 13
9. Optional
Java 8에서 도입된 Optional 클래스는 함수형 스타일로 NullPointerException을 방지하는데 유용합니다.
Optional<String> optionalString = Optional.ofNullable("Hello");
optionalString.ifPresent(System.out::println); // 값이 있을 경우 출력
10. 실용적인 예시
List<String> names = Arrays.asList("John", "Jane", "Tom", "Emily");
List<String> filteredNames = names.stream().filter(name -> name.startsWith("J")).map(String::toUpperCase).collect(Collectors.toList());
System.out.println(filteredNames); // [JOHN, JANE]
이렇게 함수형 프로그래밍을 활용하면 코드의 가독성을 높이고, 버그 발생 가능성을 줄이며, 병렬 처리에 유리한 코드 구조를 만들 수 있습니다. Java에서 함수형 프로그래밍을 활용해 코드의 품질을 향상시킬 수 있습니다.
'Java' 카테고리의 다른 글
[java] 멀티스레드 최적화 (java application batch) - 테스트 편 (0) | 2024.09.22 |
---|---|
[java] 멀티스레드 최적화 (java application batch) - 이론편 (1) | 2024.09.21 |
[java] Vavr 란? (0) | 2024.09.02 |
[java] package 에서 common 과 base 의 의미 (0) | 2024.06.11 |
[java] URL 호출해서 파일 다운로드 (InputStream) (0) | 2024.06.01 |