Language_Study/JAVA
[JAVA, App] 21.Lambda
Godwony
2020. 12. 28. 18:11
반응형
람다(Lambda)
자바에서의 람다는 함수형 프로그래밍을 지원하기 위해서 1.7에서부터 지원하기 시작한 이름없는 함수
메소드가 하나 뿐인 인터페이스를 구현해서 사용할 때 람다를 이용해서 대입하는 것이 가능
Intelli J 나 Android Studio 의 경우 메소드가 하나 뿐인 인터페이스를 anonymous를 이용해서 작성하면 람다로 자동 수정됩니다.
이전의 자바는 완전한 객체 지향 언어라서 메소드의 매개변수로 함수를 대입할 수 없었습니다.
누군가에게 작업만을 수행해달라고 요청을 해야 하는 경우 자바는 객체를 만들어서 메소드 형태로 대입한 후 요청을 했습니다.- 이런 이유로 자바로 작업을 요청하는 경우 시스템이 무거워졌습니다.
- 이러한 문제를 해결하기 위해서 등장했던 언어들이 jvm을 사용하는 Scala, Closure, Kotlin 같은 언어들입니다.
- 위의 언어들은 마지막에는 java로 번역되서 jvm위에서 실행됩니다.
자바에서도 이러한 함수형 프로그래밍을 지원하기 위해서 등장시킨 개념이 람다와 스트림입니다.
- 1.8이상에서만 사용이 가능
1.메소드가 하나 뿐인 인터페이스의 구현
- public void run 이라는 메소드를 소유한 Runnable 이라는 인터페이스가 있습니다.
- 이 인터페이스는 스레드를 만들어주는 인터페이스
1) 인터페이스를 구현한 클래스를 생성하고 인스턴스를 만들어서 사용
- 이 인터페이스는 스레드를 만들어주는 인터페이스
public class RunnableImpl implements Runnable {
@Override
public void run() {
//클래스를 만들어서 사용한다고 출력
try {
for(int i=0; i<10; i=i+1) {
Thread.sleep(1000);
System.out.println("클래스를 만들어서 사용");
}
}catch(Exception e) {
System.out.println("예외발생:" + e.getMessage());
}
}
}
2) main 메소드
public class ThreadMain {
public static void main(String[] args) {
//Runnable 인터페이스를 구현한 클래스를 이용해서 스레드 생성 및 실행
//인스턴스를 1개만 만들어서 사용한다면 메모리 낭비 - 클래스를 만들었기 때문에 클래스는 메모리에서 삭제가 안됨
Thread th1 = new Thread(new RunnableImpl());
th1.start();
//클래스를 만들지 않고 사용 - anonymous class
Thread th2 = new Thread(new Runnable() {
@Override
public void run() {
try {
for(int i=0; i<10; i=i+1) {
Thread.sleep(1000);
System.out.println("anonymous class 이용");
}
}catch(Exception e) {
System.out.println("예외:" + e.getMessage());
}
}
});
th2.start();
//람다 이용
//인스턴스를 만드는 과정도 없고 메소드 이름도 없지만 위와 동일한 기능을 수행
Thread th3 = new Thread(
()->{
try {
for(int i=0; i<10; i=i+1) {
Thread.sleep(1000);
System.out.println("람다 이용");
}
}catch(Exception e) {
System.out.println("예외:" + e.getMessage());
}
});
th3.start();
}
}
2.자바에서 람다
1) 직접 호출해서 메소드를 실행할 때는
인터페이스 변수 = 람다식;
변수.메소드();
2) 1.8 이상의 API를 사용하는 경우에는 람다식만 대입해서 메소드를 사용
3.람다식 작성 요령
(타입 매개변수, 타입 매개변수...)
-> {메소드 내용 작성; return 데이터}
- 매개변수의 자료형은 생략 가능 : 호출할 때 대입되는 데이터를 가지고 자료형을 유추
- 매개변수가 없을 때는 ()을 해야 하지만 매개변수가 1개인 경우는 ()을 생략가능
- 메소드 내용이 한 줄 이면 {} 해도 됨
- 리턴 타입은 작성할 필요없고 return을 해야 하면 return 데이터; 만 해주면 됩니다.
4.람다식을 사용할 수 있는 인터페이스는 메소드가 반드시 1개만 존재해야 합니다.
- 이러한 인터페이스는 @FuntionalInterface 라는 어노테이션을 이용해서 생성
5.람다 작성
//매개변수가 없고 리턴타입이 없는 메소드를 소유한 인터페이스
interface NoArgNoReturn{
public void method1();
}
//매개변수가 있고 리턴 타입이 없는 경우 : 원본에 작업을 해서 원본을 변환시키거나 출력하는 인터페이스
interface ArgNoReturn{
public void method2(int x);
}
//매개변수는 없고 리턴 타입만 있는 경우 : 거의 없는 경우
interface NoArgReturn{
public double method3();
}
//매개변수가 있고 리턴타입이 있는 경우 - 가장 많은 경우
interface ArgReturn{
public int method4(String str);
}
public class LambdaMain {
public static void main(String[] args) {
//매개변수가 없고 리턴도 없는 인터페이스 활용
NoArgNoReturn ob1 = () -> {System.out.println("매개변수가 없고 리턴도 없는 람다");};
ob1.method1();
//매개변수가 있는 경우 - 매개변수의 자료형은 생략이 가능, 매개변수가 1개인 경우는 ( )로 감싸지 않아도 됩니다.
ArgNoReturn ob2 = (int x) ->{System.out.println(x + 10);};
ob2.method2(100);
//매개변수는 없고 리턴만 있는 경우 - 거의 없음
NoArgReturn ob3 = () ->{return 10.3;};
double d = ob3.method3();
System.out.println(d);
//매개변수가 있고 리턴이 있는 경우 - 데이터를 가공해서 리턴하는 함수
ArgReturn ob4 = (str) ->{return Integer.parseInt(str);};
int i = ob4.method4("123219");
System.out.println(i);
}
}
6.람다식을 사용할 수 있는 인터페이스
- 1.8 버전 이상에서는 java.util.function 패키지에서 기본적인 람다식을 사용할 수 있는 인터페이스를 제공
- Consumer: 매개변수는 있고 리턴 값은 없는 메소드를 소유한 인터페이스
- Supplier: 매개변수는 없고 리턴 값만 있는 메소드를 소유한 인터페이스
- Function: 매개변수가 있고 리턴 값도 있는 메소드를 소유한 인터페이스 - 변환
- Operator: 매개변수가 있고 리턴 값도 있는 메소드를 소유한 인터페이스
- 매개변수를 누적해서 연산해서 리턴하는 메소드를 소유한 인터페이스 - 연산(합계, 평균, 최대값..)
- Predicate: 매개변수가 있는 리턴 값도 있는 메소드를 소유한 인터페이스
- 리턴 값이 boolean
- 조건에 맞는 데이터만 골라내는 메소드를 소유한 인터페이스
- 기본적으로 제너릭을 적용 - 매개변수의 자료형은 Generic으로 설정
//Consumer 인터페이스는 매개변수가 1개이고 리턴타입이 없는 메소드를 소유
Consumer <String> consumer = (t)->{System.out.println(t);};
consumer.accept("Java Lambda");
//Function 인터페이스는 매개변수가 1개이고 리턴타입이 있는 메소드를 소유
//제너릭에서 앞의 자료형은 매개변수의 자료형이고 뒤의 자료형은 리턴타입의 자료형
//데이터를 받아서 변환한 후 리턴해주는 메소드
Function <String, String> function = (str) -> {
if(str.length() <= 3) return str;
else return str.substring(0, 3) + "...";};
String r = function.apply("hi");
System.out.println(r);
r = function.apply("Hello World");
System.out.println(r);
반응형