Java 고급 주제 (Java Advanced Topics )
제네릭 (Generics)
제네릭은 Java에서 컬렉션 클래스 및 메서드에서 다양한 타입의 객체를 다루는 방법을 일반화하는 기법입니다. 제네릭을 사용하면 타입 안정성을 제공하며 코드의 재사용성과 가독성을 높일 수 있습니다.
제네릭 클래스 예제:
// 제네릭 클래스 정의 class Box<T> { private T item; public void setItem(T item) { this.item = item; } public T getItem() { return item; } } public class GenericExample { public static void main(String[] args) { // 제네릭 클래스의 인스턴스 생성 Box<Integer> integerBox = new Box<>(); integerBox.setItem(10); int num = integerBox.getItem(); // 형 변환 필요 없음 Box<String> stringBox = new Box<>(); stringBox.setItem("Hello, Generics!"); String message = stringBox.getItem(); System.out.println(num); System.out.println(message); } }
위의 예제에서 Box
클래스는 제네릭 타입 T
를 사용하여 객체를 저장하고 반환하는 메서드를 제공합니다. Box<Integer>
와 Box<String>
을 생성하여 각각 정수와 문자열을 저장하고 가져오는 예제를 보여줍니다.
람다 표현식 (Lambda Expressions)
람다 표현식은 함수형 프로그래밍 스타일을 Java에 도입하여 코드를 간결하게 만들어주는 기능입니다. 주로 함수형 인터페이스와 함께 사용되며, 익명 함수의 선언과 인스턴스화를 동시에 처리할 수 있습니다.
람다 표현식 예제:
import java.util.ArrayList; import java.util.List; public class LambdaExample { public static void main(String[] args) { List<String> names = new ArrayList<>(); names.add("Alice"); names.add("Bob"); names.add("Charlie"); names.add("David"); // 람다 표현식을 사용한 간단한 예제 names.forEach(name -> System.out.println("Hello, " + name)); // 람다 표현식을 사용하여 정렬 기준 지정 names.sort((s1, s2) -> s1.compareTo(s2)); // 함수형 인터페이스를 이용한 예제 String result = processString("Java Lambda", str -> str.toUpperCase()); System.out.println(result); // "JAVA LAMBDA" } // 함수형 인터페이스를 매개변수로 받는 메서드 public static String processString(String str, StringProcessor processor) { return processor.process(str); } // 함수형 인터페이스 정의 interface StringProcessor { String process(String str); } }
위의 예제에서는 forEach
메서드를 사용하여 리스트의 각 요소를 출력하고, sort
메서드에 람다 표현식을 사용하여 정렬 기준을 지정하는 방법을 보여줍니다. 또한, 함수형 인터페이스를 이용하여 문자열을 대문자로 변환하는 예제도 포함되어 있습니다.
스트림 API (Stream API)
스트림 API는 Java 8부터 도입된 함수형 스타일의 데이터 처리 API입니다. 컬렉션 요소를 함수형 인터페이스를 이용해 반복하고, 조작 및 질의할 수 있는 기능을 제공합니다. 스트림 API를 사용하면 병렬 처리가 간편해지며 코드의 가독성이 좋아집니다.
스트림 API 예제:
import java.util.Arrays; import java.util.List; public class StreamExample { public static void main(String[] args) { List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Edward"); // 스트림을 이용한 필터링과 매핑 names.stream() .filter(name -> name.length() > 4) .map(String::toUpperCase) .forEach(System.out::println); // 스트림을 이용한 정렬과 제한 names.stream() .sorted() .limit(3) .forEach(System.out::println); // 스트림을 이용한 병렬 처리 long count = names.parallelStream() .filter(name -> name.startsWith("A")) .count(); System.out.println("Starts with 'A': " + count); } }
위의 예제에서는 stream()
메서드를 사용하여 리스트를 스트림으로 변환하고, filter
, map
, forEach
등의 메서드를 사용하여 데이터를 처리하는 방법을 보여줍니다. 또한, 병렬 스트림을 생성하여 병렬 처리를 수행하는 예제도 포함되어 있습니다.