본문 바로가기

아옳옳의 코딩공부/아옳옳 자바코딩공부

2021-04-28자바공부(람다식 lambda함수형 인터페이스2)

반응형

어제에 이어서 람다식에 대해서 조금더 공부를 해보자 

 

함수형 인터페이스는 하나의 메소드만 가지고 있어야 한다고 배웠다 

미리정의 되어있는 함수형 인터페이스가 너무 많아 다 찾아 볼수는 없고 대표적인 것들만 보자 

 

대표적인 함수형 인터페이스이다. 

 

predicate ( 전달 인자를 근거로 참 또는 거짓을 반환) 

예제를 보면서 이해를 하자 

보면 메인에서 람다식으로 sum을 호출한것을 볼수 있다. 

호출함과 동시에 test 메소드에는 n %2 !==0 식이 들어 갈것이고 그럼과 동시에 list를 같이 넘겨준다 

sum 메소드에서는 받아온 predicate와 list를 가지고 작업을 해줄것인데 

for -each 문으로 리스트에 담겨있는 값을 하나씩 빼줄것 이지만 if 문을 통해 0인 것들은 true가 되어 s 에 저장 되고 s를 리턴 받는다 그래서 나오느 결과 값은 짝수가 12이 뿐이니 12가 찍힌 것이다. 

 

predicate 문제

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class predicateShow {
	public static <T> void show (Predicate<T> p , List<T> lst) {
		
		for(T n : lst) {
			if(p.test(n)){
				System.out.print( " "+  n + "\n" );
			}
		}		
	}	
	public static void main(String[] args) {

		List<Integer> list = Arrays.asList(1,3,8,10,11);
		System.out.println("홀수출력");
		show(n -> n%2 != 0 , list);
		
		List<Double> list2 = Arrays.asList(-1.2,3.5,-2.4,9.5);
		System.out.println("0.0보다 큰 수 출력 ");
		show(n -> n > 0.0, list2);		
	}
}

위 예시랑 비슷하다 0이 아닌 것들은 true 가 찍히고 그 숫자를 출력해준다. 

<출력결과 > 

홀수출력
1  3  11
0.0보다 큰 수 출력 
3.5  9.5

 

그리고 위처럼 Int Long Double 처럼 구체화 되어있기도 하고 Bipredicate 철머 두가지를 사용할 수도 있다. 

 

 

Supplier ( 호출시에 무언가를 제공함 ) 

메인에서 3줄까지가 get메소드를 람다식으로 선언한 부분이다.

 

그리고 아래에서 makeIntList 메소드를 호출하며 Supplier 와 숫자 5를 넘겨 준것을 볼수 있다 

그리고 아래 for문을 통하여 넘겨 받은 숫자 n(5)만큼 반복을 할 것이고 get메소드 호출로 리스트에 5가지의 난수를 넣어주면서 리스트를 리턴 해주고 있다. 

 

이거도 마찮가지로 구체화한 다양한 인터페이스들이 있다. 

 

Cunsumer (무엇인가 인자를 받아 들이기만 함 )

이렇게 보면 참 별거 없어보이지만 개인적으로 아직도 100%센트 이해가 안되서 계속 봐야 할거 같다. 

import java.util.function.BiConsumer;

class Box<T> {
	private T ob;
	public void set(T o ) { ob = o; }
	public T get () { return ob; }
}

public class Consumer {		
	
	public static void main(String[] args) {
		
		BiConsumer<Box< Integer>,Integer> c1 = (b,i) -> b.set(i);;
		BiConsumer<Box< Double>,Double> c2 = (b,d) -> b.set(d);;
		
		Box<Integer> bi = new Box<>();
		Box<Double>  bd = new Box<>();
		
		c1.accept(bi,10);
		c2.accept(bd,5.59);
		
		System.out.println(bi.get());
		System.out.println(bd.get());			
	}
}

코드를 보면 많이 복잡하다.... 나도 공부하면서도 순간 놓치면 헷가린다... 

 

일단 박스클래스가 하나 있다. ( 제네릭) 박스에는 겟터 셋터가 있고 메인으로 내려와보자 

처음에 BiConsumer(매개변수 2개 받는것) 로 매개변수를 설정 해주었다 .

매개변수로는 아까 만들어 놓은 인테저형 박스와 , 인테저가 들어가고 c1 이라는 참조변수에 담는데 메소드에는 

box 와 숫자를 매개변수로 받으면 box에 set메소드를 통해서 i값을 셋팅해주고 있다. 

그리고 박스를 인스턴스화 해주고 아까 만들어 놓은 BiConsumer의 참조변수 c1으로 accept 메소드를 호출하면서 인스턴스화한 box 1 과 10을 보내주는것을 볼수 있다. 

 

그리고 나서b1.get으로 출력을 해보면 아까 넣어준 10이 넘어와서 출력 되는것을 볼수 있다. 

말로 쓰니까 엄청 복잡한대 코드가 많이 긴게 아니니 천천히 본다면 이해 할 수 있을것이다.

아까와 다른 부분이 하나 있다. 바로 obj가 붙었다는 것인데 obj 는 아직 결정되지 않은 것이라고 보면 된다 . 

 

Function (입출력이 있다 ) 

 

화살표 처럼 T로 들어가서 R로 출력 되는 것이다. 

 

복잡해 보이지만 이것만 기억하면 된다 To앞이 매개변수 이고 To다음이 리턴형 이라고 보면 될것이다. 

중간부분에 Int , Double 보면 아에 To가 없는데 그것은 제네릭 형태로 <R>이 리턴타입이다 .

 

removeIf 를 사용한 예시

public class reMoveIf {

	public static void main(String[] args) {

		List<Integer> list1 = Arrays.asList(1,-2,3,-5);
		list1 = new ArrayList<>(list1);
		
		List<Double> list2 = Arrays.asList(0.2,0.5,0.0054,5.5 ,4.2);
		list2 = new ArrayList<>(list2);
		
		
		Predicate<Number> p = n -> n.doubleValue() < 0.0;
		list1.removeIf(p);
		list2.removeIf(p);
		
		System.out.println(list1);
		System.out.println(list2);
	}

}

이렇게 해서 0.0보다 작은 수는 제거하고 출력 된다 . 

[1, 3]
[0.2, 0.5, 0.0054, 5.5, 4.2]

 


메소드참조 4가지 유형 

@ static 메소드 참조 

static메소드(Collections.reverse) 를 사용한 예제 이다 . 

이렇게 사용하는것을 더욱 간략화 시켜줄수가 있다 .

어짜피 매개변수 I 는 같이 흘러가기 때문에 위처럼 :: 을 넣어 생략 가능하다

 

@참조변수를 통한인스턴스 메소드 참조

위랑 똑같이 짧게 하면 js :: sort 로 짧게 가능하다 

하지만 이것은 effectively final 처리가 되어있어서 다른 곳에서 변경 했을때 오류가 난다.

사실상 final 되어있다고 생각하면 된다 . 

@클래스 이름을 통한 인스턴스 메소드 참조

 

@생성자 참조 

퀴즈

class Box<T, U>{
	private T id;
	private U con;
	public Box(T id, U con) {
		this.id = id;
		this.con = con;
	}
	public void showIt() {
		System.out.println("ID: " + id + ", " +"Contents: " + con);
	}
	
}

public class BoxMaker {

	public static void main(String[] args) {
	//	BiFunction<Integer, String,Box<Integer , String>>  bf = (i,c) -> new Box<>(i,c); 
		BiFunction<Integer, String,Box<Integer, String>> bf = Box::new;
		
		Box<Integer , String >b1 = bf.apply(1,"Toy");
		Box<Integer , String >b2 = bf.apply(2,"Robot");
		
		b1.showIt();
		b2.showIt();
	}

}
반응형