익명 클래스
익명 클래스란 이름이 없다는 뜻 다시말해 나중에다시 한번 불러질 이유가없다는뜻이다.
프로그래밍적으로 말한다면 프로그램에서 한번만 사용되고 버려진다는것이다.
나중에 나중에 재사용하지않는것이다.
정리하자면
1. 재사용성이 없을때
2. 단발성으로(한번) 만 사용되어야하는 객체일경우
특징
1. 클래스 정의와 동시에 객체 생성 가능
2. 부모 클래스의 자원을 상속받아 재정의하여 사용할 계획이라면 지역 변수처럼 익명 클래스를 정의하는 것이 좋음
3. 오버라이딩 한 메소드만 사용 가능하고 새로 정의한 메소드는 외부에서 사용이 불가능함
4. 새로 정의한 메소드는 익명 클래스 내에서만 호출 가능
5.이름이 없기 때문에 생성자를 가질 수 없고 가질 필요도 없음
예시
public class Person {
String name;
public Person(String name) {
this.name = name;
}
public String name() {
return "name;
};
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person("2no") {
@Override
public String name() {
return "Eno";
}
};
System.out.println(p1.name());
}
}
실행결과
Eno
람다
익명 함수(Anonymous functions)를 지칭하는 용어
쉽게말해 메서드를 "하나의 식" 으로 표현한 것
하나의 식으로 표현하여 간략하게 표현가능하며, 메서드의 이름과 반환값이 없어지므로 익명함수 라고도 한다.
특징
1. 이름을 가질 필요가 없음
2. 코드가 간결해진다는 장점이 있지만 호출이 까다롭다.
4. 람다 stream 사용 시 성능이 for문 혹은 while문 보다 성능이떨어진다.
3. 너무 사용하게되면 오히려 가독성을 떨어 뜨릴 수 있다.
람다식 작성
(타입 매개변수) -> {실행문}
- 매개변수 : 오른쪽 중괄호 블록을 실행하기 위해 필요한 값을 제공
- 매개변수 타입은 일반적으로 언급하지 않음
- 매개변수가 하나일 경우엔 소괄호 생략 가능
- -> : 매개 변수를 이용해 중괄호 블록을 실행한다는 뜻
- 만약 return문만 중괄호에 있을 경우 중괄호와 return문 제거하고 사용하는 것이 일반적
@FunctionalInterface
- 람다식은 인터페이스 변수다?
- 람다식의 형태가 자바의 메소드를 선언하는 것처럼 보임
- 그러나 자바의 메소드는 단독 선언 불가능. 항상 클래스의 구성 멤버
- 즉, 람다식은 메소드를 가지고 있는 객체를 생성하는 것
- 이때 객체의 타입은 인터페이스
- 람다식이 익명 구현 클래스를 생성하고 객체화함
람다식과 @FunctionalInterface 예시
@FunctionalInterface
public interface MyFunctionalInterface{
public int sum(int num1,int num2);
}
//Main
MyFunctionalInterface mi = (num1,num2) -> num1+num2;
System.out.println(mi.sum(3,6));
Java에서 제공하는 FunctionalInterfaces
함수형 인터페이스DescripterMethod
스트림 API
- 데이터를 추상화하고 처리하는데 자주 사용되는 함수들을 정의함
특징
- 자바에서 배열이나 컬렉션을 사용할 때 원래는 반복문, 반복자 사용
- 가독성이 떨어지고 코드 재사용이 불가능하다는 단점 존재
- 이를 극복하기 위해 나온 API
- 원본 데이터를 변경하지 않음
- 필터, 맵 기반의 API를 사용해 지연 연산을 수행하여 성능을 최적화함
구현
- 컬렉션
- Collections 인터페이스에는 stream() 메소드가 정의되어 있음
- 컬렉션 프레임워크 중 Map 역시 stream 메소드 사용 가능
Map<String,Integer>map = new HashMap<>();
map.entrySet().stream()
.filter(e->e.getKey().contains("no"))
.filter(e->e.getValue()>150)
.forEach(e->System.out.println(e.getKey()+e.getValue()));
- 람다 표현식
Stream stream = Stream.iterate(2,n->n+2);
stream.forEach(System.out::println);
문제1 - 자바의 람다식은 왜 등장했을까?
함수형 인터페이스와 람다식이 등장한 이유를 알기 위해 다음 Person 인터페이스와 이를 구현한 Student 클래스를 보자.
interface Person {
void study(String subject){}
}
class Student implement Person {
@Override
public void study(String user) {
System.out.println(user + "2no");
}
}
인터페이스를 구현하는데 상당히 많은 줄을 차지한다. 이것을 해결하기 위해 자바8에서부터 람다식을 지원한다. 람다식은 코드를 간결하게 만들기 위해 등장한 만큼 추측할 수 있는 모든 정보를 제거하여 간결하게 표현한다. 위의 코드를 람다식으로 표현하면 다음과 같다.
Person user1 = (user) -> { System.out.println(user + "2no"); }
1. user1의 타입인 Person을 통해 타입의 유추가 가능하므로 람다식에서는 이를 생략한다.
2. 함수형 인터페이스에서는 메소드가 하나만 정의되어 있기 때문에 메소드명을 생략한다.
3. 매개변수와 인자의 순서를 매칭하믕로써 타입도 유추가 가능하기 때문에 이를 생략한다.
문제2 - 람다식과 익명 클래스는 어떤 관계가 있을까? - 람다식의 문법은 어떻게 될까?
1. 익명 내부 클래스는 새로운 클래스를 생성하지만, 람다는 새로운 메서드를 생성하여 포함한다.
- 람다는 static 이든, 객체 사용을 위한 non-static 이든, 메서드로 생성된다.
- 이에 반해 익명 내부 클래스는 새로운 클래스파일이 생성된다.
2. 익명 내부 클래스의 this : 새로 생성된 클래스, 람다의 this : 람다식을 포함하는 클래스
- 위와 완벽하게 일맥상통하는 말이다.
- 새로운 클래스를 만들기 때문에, 익명 내부클래스에서의 this 는 해당 클래스를 가리킨다.
- 새로운 클래스를 만드는 게 아니고 그냥 메서드를 만드는 람다는, 메서드 즉 람다가 있는 클래스를 가리킨다.
람다식의 문법
메서드를 하나의 식으로 표현한 것으로, 간략하고 명확한 식으로 함수를 표현할 수 있다.
RunSomething runSomething = new RunSomething() {
@Override
public void doIt() {
System.out.println("Lambda");
}
};
위의 익명 내부 클래스를 람다식으로 사용해서 간단하게 표현하면 다음과 같이 6줄의 코드를 1줄로 표현할 수 있다.
RunSomething runSomething = () -> System.out.println("Lambda");
'인프런 워밍업 스터디 > 과제' 카테고리의 다른 글
[인프런 워밍업 스터디 클럽 0기 - BE] #6 과제 (0) | 2024.02.26 |
---|---|
[인프런 워밍업 스터디 클럽 0기 - BE] #5 과제 (0) | 2024.02.23 |
[인프런 워밍업 스터디 클럽 0기 - BE] #4 과제 (0) | 2024.02.22 |
[인프런 워밍업 스터디 클럽 0기 - BE] #2 과제 (0) | 2024.02.20 |
[인프런 워밍업 스터디 클럽 0기 - BE] #1 과제 (0) | 2024.02.19 |