선언없이 실행 가능한 method이다.간결하게 만들 수 있음가독성이 향상됨병렬 처리에 유리익명클래스(Anonymous class)는 재사용이 불가능함콜 스택 추적이 다소 어려움완전탐색을 하는 경우 실행 속도가 느릴 수 있음매개변수부와 선언부로 나눔//(argument) -> {body} 구문을 사용하여 작성
( ) -> {/* 함수 코드 작성 */}
함수형 인터페이스(Functional Interface)에 접근하여 사용함수형 인터페이스란 한개의 abstract method를 가지는 인터페이스로, 동적 메서드 구현 후 사용하기 위해 정의()를 생략할 수 있음{}를 생략할 수 있음;은 붙이지 않음{}는 생략할 수 없음;은 붙이지 않음| 함수형 인터페이스 | 메서드 | 매개변수 | 반환값 |
|---|---|---|---|
| java.lang.Runnable | void run() | ✖ | ✖ |
| Supplier < T > | T get() | ✖ | ○ |
| Consumer < T > | void accept(T t) | ○ | ✖ |
| Function< T, R > | R apply(T t) | ○ | ○ |
| Predicate < T > | boolean test(T t) | ○ | ○ |
Instrument Interface@FunctionalInterface //람다 (중복 정의를 막아주는 어노테이션)
public interface Instrumnet {
public String play(String instrument);
}
main
Interface method에 접근하여 람다식 사용
public class Lambda1 {
public static void main(String[] args) {
Instrumnet it = new Instrumnet() {
@Override
public String play(String instrument) { // 구현부 (일회용 클래스)
return instrument + "을(를) 연주합니다.";
}
};
System.out.println(it.play("피아노"));
}
}
람다 전 (before) ↔ 람다 후 (after)Instrumnet it = new Instrumnet() {
@Override
public String play(String instrument) { // 구현부 (일회용 클래스)
return instrument + "을(를) 연주합니다.";
}
};
Instrumnet it2 = (String itm) -> {
return itm + "을(를) 연주합니다 ";
};
String playText = it2.play("드럼");
System.out.println(playText);
최종 형태
Instrumnet it6 = itm -> itm + "을(를) 연주합니다 " ;
매개변수의 자료형 생략매개변수명을 바꿈 Instrumnet it3 = (itm) -> {
return itm + "을(를) 연주합니다 ";
};
매개 변수가 하나면 괄호를 생략 Instrumnet it4 = itm -> {
return itm + "을(를) 연주합니다 ";
};
public class Lamdba2 {
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();
}
}
Supplier<LocalDate> c = () -> LocalDate.now();
Supplier<String> d = () -> {
LocalDate now = LocalDate.now();
return now.format(DateTimeFormatter.ofPattern("yyyy년 MM월 dd일"));
// 소문자 y (년) , 대문자 M (월) , 소문자 d (일)
};
System.out.println(c.get());
System.out.println(d.get());
Consumer<String> e = name -> {
System.out.println("이름: " + name);
System.out.println("오늘 날짜: " + d.get());
};
e.accept("홍길동");
method 참조 표현식
// 메서드 참조 표현식 ( [인스턴스] :: [메서드명 또는 new])
Consumer<String> f = System.out::println;
f.accept("출력");
List<String> names = new ArrayList<>();
names.add("김동민");
names.add("김두두");
names.add("장진원");
names.add("조병철");
// #1
Consumer< String > g = name -> System.out.println("이름: " + name + "님");
names.forEach(g);
/////////////////////// 또 다른 방법 //////////////////////////
// #2
names.forEach(name -> System.out.println("이름: " + name + "님"));
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");
구현의 두 가지 방법
for(Entry<String,String> entry : userMap.entrySet()){
System.out.println("key: " + key);
System.out.println("value: " + value);
System.out.println();
}
세련된 방법
userMap.forEach((key,value) ->{
System.out.println("key: " + key);
System.out.println("value: " + value);
System.out.println();
});
Function<String, Integer> h = num -> Integer.parseInt(num);
int convertStrNum1 = h.apply("100000");
int convertStrNum2 = h.apply("200000");
System.out.println(convertStrNum1+convertStrNum2);
Predicate<String> p = str -> str.startsWith("김");
Predicate<String> p2 = str -> str.startsWith("이");
System.out.println(p.or(p2).test("김준일"));
Function<Predicate<String>, Boolean> function1 =
predicate -> predicate.or(str -> str.startsWith("이")).test("김준일");
boolean rs = function1.apply(str -> str.startsWith("김"));
System.out.println(rs);
// 스트림 -> 일회용
Stream<String> stream = nameList.stream().filter(name -> name.startsWith("김"));
//stream.forEach(name -> System.out.println(name));
List<String> newList = stream.collect(Collectors.toList());
newList.forEach(str -> System.out.println(str));
// 한줄로 표현
nameList.stream()
.filter(name -> name.startsWith("김"))
.collect(Collectors.toList())
.forEach(System.out::println);
//.forEach(name -> System.out.println(name)); //똑같음
람다식이 아닌 일반 메서드를 참조시켜 선언하는 방법3가지의 조건을 만족해야 한다.타입 = 메서드의 매개변수 타입개수 = 메서드의 매개변수 개수반환형 = 메서드의 반환형클래스이름 :: 메서드 이름으로 참조할 수 있다. 이렇게 참조하면 함수형 인터페이스로 반환된다