IT Developer/Java

Java 기초 <12. Java 5~17 주요 기능 변화 (제네릭, 스트림, 람다, 레코드 등)>

TEMA_ 2025. 3. 13. 09:25
반응형

자바 Java

12. Java 5~17 주요 기능 변화 (제네릭, 스트림, 람다, 레코드 등)

 

안녕하세요! 태마입니다.

Java 기초 강좌입니다.

 

강좌의 경우 

1. 주제 간단 정리

2. 상세 주제 정리

으로 이루어져 있습니다.

 

자바 Java

포스팅 시작하겠습니다 :)

1. 주제 간단 정리

 

1. Java 5: 제네릭(Generics) 도입

Java 5는 **제네릭(Generics)**을 도입하여 타입 안전성을 높이고, 코드 재사용성을 극대화하는 중요한 기능을 추가했습니다.
제네릭을 사용하면 컴파일 타임에 타입을 체크할 수 있어 런타임 오류를 예방할 수 있습니다.
✔ 제네릭은 컬렉션 프레임워크와 함께 사용되며, 타입 매개변수를 지정하여 다양한 타입에 대해 안전하게 작업할 수 있습니다.

제네릭 예제

import java.util.*;

public class GenericsExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("Generics");

        // 타입 안전성을 제공하며, 컴파일 타임에 타입 체크
        for (String item : list) {
            System.out.println(item);
        }
    }
}

📌 제네릭을 사용하면 타입 안전성이 보장되며, 여러 타입을 처리할 수 있는 코드가 작성됨.


2. Java 8: 스트림(Stream)과 람다(Lambda) 도입

Java 8은 **스트림(Stream)**과 람다(Lambda) 표현식을 도입하여 함수형 프로그래밍 스타일을 가능하게 했습니다.

람다(Lambda) 표현식

람다 표현식은 익명 함수로, 간결한 코드컬렉션 처리, 이벤트 리스너 등을 처리할 수 있습니다.

public class LambdaExample {
    public static void main(String[] args) {
        // 람다 표현식 사용
        List<String> list = Arrays.asList("Java", "Python", "C++");
        list.forEach(item -> System.out.println(item));
    }
}

📌 람다 표현식을 사용하면 코드가 간결해지고, 컬렉션을 처리하는 방식이 매우 직관적


스트림(Stream)

스트림은 컬렉션 데이터를 처리하기 위한 추상화된 API로, 데이터를 선언적 방식으로 처리할 수 있게 해줍니다.
filter(), map(), reduce() 등을 사용하여 데이터를 쉽게 변형하고, 조작할 수 있습니다.

import java.util.*;
import java.util.stream.*;

public class StreamExample {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("Java", "Python", "C++", "JavaScript");

        // 스트림을 이용해 "J"로 시작하는 문자열 필터링
        list.stream()
            .filter(item -> item.startsWith("J"))
            .forEach(System.out::println); // Java, JavaScript 출력
    }
}

📌 스트림을 사용하면 복잡한 데이터를 선언적으로 처리할 수 있어 코드의 가독성이 높아짐.


3. Java 14: 레코드(Record) 도입

**레코드(Record)**는 불변 객체를 만들기 위한 새로운 클래스 유형입니다.
레코드는 자동으로 생성자, toString(), equals(), hashCode() 메서드를 생성하여, 불변 객체를 만들 때 유용합니다.

레코드 예제

public class RecordExample {
    public static void main(String[] args) {
        // 레코드 클래스 생성
        Person person = new Person("John", 30);
        System.out.println(person); // Person[name=John, age=30] 출력
    }
}

record Person(String name, int age) { }  // 레코드 클래스

📌 레코드는 데이터만 저장하고, 불필요한 메서드를 자동으로 생성하여 코드의 간결함을 제공함.


4. Java 16: 패턴 매칭(Pattern Matching) 도입

Java 16에서 도입된 **패턴 매칭(Pattern Matching)**은 instanceof 연산자의 사용을 더 간결하게 해줍니다.
패턴 매칭은 **instanceof**와 캐스팅을 합쳐서 하나의 표현식으로 처리할 수 있도록 도와줍니다.

패턴 매칭 예제

public class PatternMatchingExample {
    public static void main(String[] args) {
        Object obj = "Hello, Java!";
        
        if (obj instanceof String str) {  // 패턴 매칭을 사용하여 타입 체크 후 변수 선언
            System.out.println(str.length());  // 문자열의 길이 출력
        }
    }
}

📌 instanceof와 변수를 동시에 선언하고 사용할 수 있어 코드가 간결해짐.

반응형

2. 상세 주제 정리

 

1. 제네릭을 활용한 컬렉션 예제

제네릭을 사용하여 타입 안전성을 제공하는 컬렉션을 만들어 보겠습니다.

제네릭 컬렉션 예제

import java.util.*;

public class GenericsCollectionExample {
    public static void main(String[] args) {
        // 제네릭을 사용한 리스트
        List<Integer> numbers = new ArrayList<>();
        numbers.add(10);
        numbers.add(20);
        numbers.add(30);

        // 타입 안전성이 보장되어 정수만 추가 가능
        for (int number : numbers) {
            System.out.println(number);  // 10, 20, 30 출력
        }
    }
}

📌 제네릭을 사용하면 코드에서 잘못된 타입을 사용할 경우 컴파일 타임에 오류가 발생하여 안전성을 확보


2. 스트림을 활용한 데이터 처리 예제

Java 8에서 도입된 스트림을 사용하여 컬렉션 데이터를 간결하게 처리하는 방법을 살펴봅니다.

스트림으로 리스트 처리 예제

import java.util.*;
import java.util.stream.*;

public class StreamProcessingExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // 짝수만 필터링하여 리스트 출력
        List<Integer> evenNumbers = numbers.stream()
                                            .filter(n -> n % 2 == 0)
                                            .collect(Collectors.toList());

        System.out.println(evenNumbers);  // [2, 4, 6, 8, 10] 출력
    }
}

📌 스트림을 사용하면 필터링, 매핑, 집합 등을 쉽게 처리할 수 있으며, 코드가 간결하고 가독성이 좋아짐


3. 레코드(Record)를 활용한 불변 객체 생성

레코드를 사용하여 불변 객체를 쉽게 생성하는 방법을 살펴봅니다.

레코드를 사용한 데이터 클래스 예제

public class RecordUsageExample {
    public static void main(String[] args) {
        // 레코드 클래스 사용
        Person person = new Person("Alice", 25);
        System.out.println(person); // Person[name=Alice, age=25] 출력
    }
}

record Person(String name, int age) { }  // 레코드 클래스 정의

📌 레코드를 사용하면 데이터만 가진 객체를 간단하게 정의하고, 불필요한 코드(예: toString())를 자동으로 생성


4. 패턴 매칭을 활용한 코드 간결화

Java 16에서 도입된 패턴 매칭을 사용하여 타입 검사와 변수 선언을 동시에 처리하는 방법을 살펴봅니다.

패턴 매칭 예제

public class PatternMatchingUsageExample {
    public static void main(String[] args) {
        Object obj = "Pattern Matching in Java";

        // 패턴 매칭 사용
        if (obj instanceof String str) {
            System.out.println(str.length());  // 문자열의 길이 출력
        }
    }
}

📌 패턴 매칭을 사용하면 코드가 간결해지고, 타입 검사와 캐스팅을 동시에 처리할 수 있어 가독성 향상


지금까지 Java 5~17의 주요 기능 변화를 배웠어요!
👉 "이제 Java 18 이후의 최신 트렌드에 대해 배우고 싶다면?"
다음 회차에서 Java 18 이후의 주요 기능과 트렌드에 대해 다뤄봅시다!

반응형