메소드를 하나의 식으로 간단하게 표현한것이다.
형식
(자료형 변수) -> {(메소드 실행코드;)}
함수형 인터페이스에서만 람다식을 사용할수있다.
MyMath m = new MyMath(){
public int add(int a, int b){
return a+b;
}
};
System.out.println(m.add(1,2));
jdk8
버전 이전에는 익명의 내부클래스를 사용을 했었음
MyMath m = (int a,int b)->{return a+b;};
jdk8
이후 부터는 람다식이 도입되어서 코드를 간결하게 할 수 있다.
MyMath m = (a,b) -> a+b;
매개변수타입이 생략 가능하고 return
문이 하나인경우 생략가능하다.
예제)
new Thread(new Runnable(){
public void run(){
for(int i=0; i<=10; i++){
System.out.println(i+(Hello));
}
}
}).start();
위 코드를 람다식으로 바꿔보자
new Thread(() -> {
for(int i=0; i<=10; i++){
System.out.println(i+(hello));}
}).start();
Runnable
메소드 파라미터가 없기때문에 람다식에서는 아무것도 적지않고 실행문장만 적어주면 된다.
예제) (1초에 한번씩 시간을 출력하는 스레드를 람다식으로 출력)
new Thread(()->{
SimpleDateFormat sdf = new SimpleDateFormat("YYYY/MM/dd HH:mm:ss");
while(true){
String s1 = sdf.fomat(new Date());
System.out.println(s1);
try{
Thread.sleep(1000);
}catch(InterruptedException ie){
System.out.println(ie.getMessage());
}
}
}).start();
시간을 출력하는 클래스는 Calendar
라고 있지만 객체와 변수를 해당하는 만큼 만들어줘야하기때문에 번거롭다.
Consumer
는 매개변수는 받아들이고 return
값은 반환하지 않는다.
HashSet
또한 하나의 값을 가지고 Consumer Interface
를 사용한다.
ArrayList<String> list = new ArrayList<>();
list.add("카메라");
list.add("사진");
list.add("렌즈");
list.forEach(new Consumer<String>(){
public void accept(String t){
System.out.println(t);}
});
이처럼 accept(String t)
의 값을 반복해서 받아서 출력한다. 반환값은 없다.
list.forEach((t)->System.out.println(t));
위 코드를 람다식으로 바꾼것이다.
Biconsumer
는 두개의 입력값 <키,값>을 가진다. return
문이 없다.
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "고길동");
map.put(2, "둘리");
map.put(3, "또치");
map.forEach(new BiConsumer<Interger, String>() {
public void accept(Integer t, String u) {
System.out.println(t+","+u)
}
});
accept(Integer t, String u)
코드에 키값과 문자값이 반복해서 출력된다.
forEach메소드를 람다식으로 바꾼 코드
map.forEach((t,u)->System.out.println(t+","+u));
Stream
은 배열 또는 컬렉션 객체에 들어있는 데이터를 이용해서 다양하게 처리를 할 수 있는 객체이다.
컬렉션이나 배열을 사용해서 처리를 하려면 배열에 대한 반복을 해줘야하고, 반복루프 안에 여러개의 로직을 넣어 중첩구조를 가져가거나 이를 위한 별도의 함수를 만들어야하고 버그를 유발하기 쉽다. Stream
은 반복을 하지않고 개별 엘리먼트에 대한 로직을 수행할 수 있다.
ArrayList<String> list = new ArrayList<String>();
list.add("고길동");
list.add("둘리");
list.add("또치");
Stream<String> s = list.Stream();
s.forEach((t)->{System.out.println(t);});
Stream
은 딱 한번만 사용된다.
Stream<String> s2 = list.Stream();
s2.sorted().forEach.(t->System.out.println(t));
sorted
는 정렬해준다.
ArrayList<Student> list1 = new ArrayList<Student>();
list1.add(new Student(1, "고길동", 80));
list1.add(new Student(2, "둘리", 80));
list1.add(new Student(3, "또치", 80));
list1.add(new Student(4, "마이클", 80));
Stream<Student> s3 = list1.stream();
s3.forEach(s->System.out.println(s));
Stream<Student> s4 = list1.Stream();
s4.Filter((t) -> t.getNum()%2==0).forEach(s4->System.out.println(s4));
짝수의 번호만 출력하고싶을때는 stream
의 여러 함수중 filter
함수를 사용하면된다.