[Lecture/Java] 06강 - 제네릭과 람다식

김찬미·2025년 5월 28일

6강 - 제네릭과 람다식

  • 제네릭 타입
  • 제네릭 메소드와 타입 제한
  • 람다식

✅ 제네릭 타입

클래스, 인터페이스, 메소드를 정의할 때 타입 매개변수(타입 파라미터)를 선언하고 사용할 수 있음
→ 자바 프로그램의 재사용성을 높이고 오류를 줄이는 방법

✔️제네릭의 장점

  • 여러 유형에 걸쳐 동작하는 일반화된 클래스나 메소드 정의
  • 자료형을 한정함으로써 컴파일 시점에 자료형 검사 가능
  • 캐스트(형변환) 연산자의 사용 불필요

제네릭 클래스

  • 클래스 정의에서 타입 파라미터를 선언함
    • 클래스를 사용할 때는 타입을 명시해야 함
  • 타입 파라미터는 참조형만 가능
    • 필드의 자료형, 메소드 반환형, 인자의 자료형으로 사용 가능
  • 컴파일 할 때, 명확한 타입 검사를 수행할 수 있음
    • 메소드 호출 시 인자의 유형이 맞는지
    • 메소드 호출의 결과를 사용할 때 유형이 맞는지
  • 자료형 매개변수로 가지는 클래스와 인터페이스를 제네릭 타입이라고 함

🔹제네릭 클래스의 정의

접근제어자 class 클래스이름<T1,T2,...> {
	... ...
}
  • 타입 파라미터는 타입을 전달 받기 위한 것
  • 타입 파라미터 이름은 관례적으로 E, K, V, N, T ... 를 사용함

🔹Raw 타입

타입 매개변수 없이 사용되는 제네릭 타입

  • 제네릭 타입인데 일반 타입처럼 사용하는 경우
  • 타입 매개변수를 Object로 처리함
class Data<T> {
	private T t;
    public Data(T t) {this.t = t;}
	public void set(T t) {this.t = t;}
	public T get() {return t;}
}

Data는 제네릭 타입 Data<T>raw 타입


✅ 제너릭 메소드와 타입 제한

제네릭 메소드

자료형을 매개변수로 가지는 메소드
→ 하나의 메소드 정의로 여러 유형의데이터를 처리할 때 유용함

public <T> void swap(T[] array, int i, int j) {
	T temp = array[i];
    array[i] = array[j];
    array[j] = temp;
}
  • 인스턴스 메소드와 static 메소드 모두 제네릭 메소드로 정의 가능
    *제네릭 메소드를 호출할 때, 타입을 명시하지 않아도 됨
    • 전달되는 인자에 의해 타입 추론 가능

🔸제네릭의 타입 제한

<T extends Number> // T를 상한으로 정할 수 있음
// T에 주어지는 실제 자료형은 Number의 서브 클래스여야 함


🔸제네릭 타입 사용 시 유의사항

  • 기본 자료형은 타입 매개변수로 지정할 수 없음
Data<int> d = new Data<>(); //오류
  • 타입 매개변수로 객체 생성을 할 수 없음
class Data<T> {private T t1 = new T();} //오류
  • 타입 매개변수의 타입으로 static 데이터 필드를 선언할 수 없음
class Data<T> {private static T t2;} //오류
  • 제네릭 타입의 배열을 선언할 수 없음
Data<Integer>[] arrayOfData; //오류

✅ 람다식

인터페이스를 구현하는 익명 클래스의 객체 생성 부분을 수식화한 것

  • 구현할 것이 1개의 추상 메소드뿐인 경우, 간단히 표현 가능
Runnable runnable = new Runnable() {
	public void run() {
    ... }
}

람다식 구문

  • 메소드 매개변수의 괄호, 화살표, 메소드 몸체로 표현
    • 인터페이스 객체 변수 = (매개변수 목록) -> {실행문목록};
Runnable runnable = () -> {...};

람다식 기본 문법

🔹 기본 형태

인터페이스 변수 = (매개변수) -> { 실행문 };

🔹 조건

  • 함수형 인터페이스여야 함 → 추상 메소드 1개만 존재해야 함
  • 익명 클래스 전체는 람다식 불가, 구현부만 람다 가능

문법 간소화 규칙

형태예시
매개변수 타입 생략(a, b) -> a + b
매개변수 1개 → 괄호 생략a -> a * 2
매개변수 없음() -> 실행문
실행문 1개 → 중괄호 생략(x) -> System.out.println(x)
실행문이 return만 있을 때 → return, {}, ; 생략(a, b) -> a + b
// Runnable은 추상 메소드 1개 (run)
Runnable r = () -> System.out.println("my thread");

// 함수형 인터페이스의 계산 메소드
MyFunction f = (a, b) -> a + b;

람다식의 활용

함수형 인터페이스 functional interface

  • 1개의 추상 메소드만 가지는 단순한 인터페이스

  • 패키지 java.util.function에서 표준 함수형 인터페이스가 제네릭 인터페이스로 제공

  • 함수형 인터페이스를 구현하는 클래스를 정의할 때, 익명 클래스 정의를 활용할 수 있으나 람다식이 효율적

💡 표준 함수형 인터페이스의 예

  • Consumer<T>void accept(T t)를 가짐
  • Supplier<T>T get() 메소드를 가짐
  • Functional<T, R>R apply(T t)를 가짐
public class Main {
    public static void main(String args[]) {
        Thread thd = new Thread(() - > System.out.println("hi"));
        thd.start();
    }
}


import java.util.function.*;

public class Main {
    public static void main(String args[]) {
        Supplier <Integer> rand = () - > {
            Integer r = (int)(Math.random() * 10);
            return r;
        };
        int a = rand.get();
        System.out.println(a);
    }
}
profile
백엔드 지망 학부생

0개의 댓글