728x90
목차
1. 람다식
■ 람다식이란?
- 람다식은 객체를 정의 및 생성함(익명클래스와 같음)
- 람다는 메소드가 주체임
- 람다는 추상메소드가 하나인 인터페이스만 정의 가능
- 독립적으로 존재 불가능하기 때문에 적용 가능한 대상 필요
■ 람다식 매개변수
- 매개변수의 자료형을 생략 가능
- 매개변수의 이름 변경 가능
- 매개변수가 하나이면 매개변수를 감싸는 괄호 생략 가능
■ 람다식 구현부
- 구현부의 명령이 하나일 때 중괄호 생략 가능
- 중괄호를 생략하고 리턴 자료형이 정해져 있으면 리턴값으로 사용됨
- 중괄호를 생략하면 return을 적을 수 없음
- 지역변수를 매개변수에 넣어 사용하지 않아도 바로 사용 가능
- 지역변수명과 같은 변수명을 매개변수명으로 사용 불가
■ 인터페이스
- 기본 함수형 인터페이스(파라미터가 없거나 하나임)
함수형 인터페이스 메소드 매개변수 반환값 java.lang.Runnable void run() X X Supplier<T> T get() X O Consumer<T> void accept(T t) O X Function<T, R> R apply(T t) O O Predicate<T> boolean test(T t) O O
- 파라미터가 두개인 함수형 인터페이스
함수형 인터페이스 메소드 매개변수 반환값 BiConsumer<T,U> void accept(T t, U u) O O BiFunction<T,U,R> R apply(T t, U u) O O BiPredicate<T,U boolean test(T t, U u) O O
- 파라미터 타입이 반환타입과 일치하는 인터페이스
함수형 인터페이스 메소드 매개변수 반환값 UnaryOperator<T> T apply(T t) O O BinaryOperator<T> T apply(T t, T t) O O
2. 예시
■ Instrument
package j24_람다;
// 함수형 인터페이스로 지정하는것
// 추가적인 추상메소드 작성을 막아줌
// default 메소드는 여러개 작성 가능
@FunctionalInterface
public interface Instrument {
public String play(String instrument);
}
■ Lamda1
package j24_람다;
public class Lamda1 {
public static void main(String[] args) {
Instrument instrument = new Instrument() {
@Override
public String play(String instrument) {
return instrument + "을(를) 연주합니다.";
}
};
Instrument instrument2 = (String itm) -> {
return itm + "을(를) 연주합니다.";
};
// 매개변수의 자료형을 생략할 수 있다.
// 매개변수의 이름을 바꿀 수 있다.
Instrument instrument3 = (itm) -> {
return itm + "을(를) 연주합니다.";
};
// 매개변수가 하나이면 매개변수를 감싸는 괄호를 생략할 수 있다.
Instrument instrument4 = itm -> {
return itm + "을(를) 연주합니다.";
};
// 구현부의 명령이 하나일 때 중괄호를 생략할 수 있다.
// 이때 리턴자료형이 정해져있으면 리턴값으로 사용이 된다.
// 중괄호를 생략하면 return을 적을 수 없음
Instrument instrument5 = itm -> itm + "을(를) 연주합니다.";
// 지역변수를 매개변수에 넣어 사용하지 않아도 바로 사용 가능
// 지역변수명과 같은 변수명을 매개변수명으로 사용 불가
int result = 10 + 20;
Instrument instrument6 = itm -> itm + "을(를) 연주합니다." + result;
System.out.println(instrument2.play("기타"));
System.out.println(instrument.play("트럼펫"));
System.out.println(instrument6.play("피아노"));
}
}
■ Lamda2
package j24_람다;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Lamda2 {
public static void main(String[] args) {
// 1. Runnable - run()
Runnable a = () -> System.out.println("실행");
Runnable b = () -> {
System.out.println("여");
System.out.println("러");
System.out.println("명");
System.out.println("령");
System.out.println("실");
System.out.println("행");
};
a.run();
b.run();
// 2. Supplier<T> - T get()
Supplier<LocalDate> c = () -> LocalDate.now();
Supplier<String> d = () -> {
LocalDate now = LocalDate.now();
return now.format(DateTimeFormatter.ofPattern("yyyy년 MM월 dd일"));
};
System.out.println(c.get());
System.out.println(d.get());
// 3. Consumer<T> - void accept(T t)
Consumer<String> e = name -> {
System.out.println("이름 : " + name);
System.out.println("오늘 날짜 : " + d.get());
};
e.accept("이종현");
// 메소드 참조 표현식 ([인스턴스] :: [메소드명 또는 new])
Consumer<String> f = System.out :: println;
f.accept("출력");
List<String> names = new ArrayList<>();
names.add("김동민");
names.add("김두영");
names.add("장진원");
names.add("조병철");
Consumer<String> g = name -> System.out.println("이름 : " + name + "님");
names.forEach(g);
names.forEach(name -> {
System.out.println("이름을 출력합니다.");
System.out.println("이름 : " + name);
System.out.println();
});
Map<String, String> userMap = new HashMap<>();
userMap.put("username", "aaa");
userMap.put("password", "1234");
userMap.forEach((key, value) -> {
System.out.println("key : " + key);
System.out.println("value : " + value);
System.out.println();
});
// 4. Function<T, R>
Function<String, Integer> h = num -> Integer.parseInt(num);
int convertStrNum1 = h.apply("10000");
int convertStrNum2 = h.apply("20000");
System.out.println(convertStrNum1 + convertStrNum2);
// 5. Predicate<T>
Predicate<String> p1 = str -> str.startsWith("김");
Predicate<String> p2 = str -> str.startsWith("이");
Function<Predicate<String>, Boolean> function1 =
predicate -> predicate.or(str -> str.startsWith("이")).test("김준일");
boolean rs = function1.apply(str -> str.startsWith("김"));
System.out.println(rs);
List<String> nameList = new ArrayList<>();
nameList.add("김종환");
nameList.add("고병수");
nameList.add("김상현");
nameList.add("김준경");
// 스트림 -> 일회용
Stream<String> stream = nameList.stream().filter(name -> name.startsWith("김"));
// stream.forEach(name -> System.out.println(name));
List<String> newList = stream.collect(Collectors.toList());
System.out.println(newList);
System.out.println("========================================");
nameList.stream()
.filter(name -> name.startsWith("김"))
.collect(Collectors.toList())
.forEach(System.out::println);
}
}