파라미터를 입력 받아 그것을 소비하는 함수형 인터페이스
소비라는 것은 함수가 이용된다고 생각하면 된다. 리턴이 되지 않고 함수 내에서 사용이 되고 없어진다.
참고로 Consumer 는 void 로 반환값이 없지만, 람다의 body에 일반 표현식이 있으면 호환이 가능하다.
1
2
3
4
5
6
7
8
9
10
11
12
특별한 void 호환 규칙
람다의 바디에 일반 표현식이 있으면 void를 반환하는 함수 디스크립터와 호환된다.
(물론 파라미터 리스트도 호환되어야 함).
예를 들어 다음 두 행의 예제에서 List의 add 메소드는
Consumer 콘텍스트(T -> void)가 기대라는 void를 반환하지만 유효한 코드다.
//Predicater는 불리언 반환값을 갖는다
Predicater<String> p = s -> list.add(s);
//Consumer는 void 반환값을 갖는다.
Consumer<String> b = s -> list.add(s);
importjava.util.function.*;publicclassMain{publicstaticvoidmain(String[]args){Consumer<String>consumer=(s)->System.out.println(s);consumer.accept("A String.");BiConsumer<String,String>biConsumer=(t,u)->System.out.println(t+","+u);// <String,String> 이므로 모두 String 전달biConsumer.accept("Hello","world");// 오토박싱/ 언방식 사용하면 비효율적이다.Consumer<Integer>integerConsumer=(x)->System.out.println(x);integerConsumer.accept(10);// 값이 들어갈 땐 오토박싱 출력할 때 언박싱IntConsumerintConsumer=(x)->System.out.println(x);intConsumer.accept(5);// t는 <>안에 값 x는 objIntconsumber의 int의 자료형이 들어간다.ObjIntConsumer<String>objIntConsumer=(t,x)->System.out.println(t+": "+x);objIntConsumer.accept("x",1024);// ObjLongConsumer,ObjDoubleConsumer// 총 4가지 타입이 있다.}}
importjava.util.function.BooleanSupplier;importjava.util.function.IntSupplier;importjava.util.function.Supplier;publicclassMain{publicstaticvoidmain(String[]args){Supplier<String>supplier=()->"A String";System.out.println(supplier.get());// get()을 해서 출력을 한다.// BiSupperlier는 입력은 여러 개 할 수 있지만, // 출력은 하나 밖에 못하기 때문에 없다.BooleanSupplierboolsup=()->true;System.out.println(boolsup.getAsBoolean());// 이것은 getAsBoolean()으로 출력한다.// IntSupplier, LongSupplier, DoubleSupplierIntSupplierrollDice=()->(int)(Math.random()*6);for(inti=0;i<10;i++){System.out.println(rollDice.getAsInt());}intx=4;IntSupplierintSupp=()->x;//지역변수에도 접근할 수 있다.// 람다식을 활용할 때 모든 변수에 접근하여 활용할 수 있다.// 고정되어있는 값뿐만아니라 동적으로도 주변 값들을 공급할 수 있다.System.out.println(intSupp.getAsInt());}}
publicclassMain{publicstaticvoidmain(String[]args){Function<String,Integer>func=(s)->s.length();// s 는 String타입, s.length() 는 IntegerSystem.out.println(func.apply("Strings"));//apply로 출력한다// Bi가 붙으면 2개의 값 입력BiFunction<String,String,Integer>biFunction=(s,u)->s.length()+u.length();System.out.println(biFunction.apply("one","two"));//6// IntFunction<R>은 리턴 자료형// P type Funtion은 입력을 P타입으로 받는다.IntFunction<String>intFunction=(value)->String.valueOf(value);// "" + value도 가능.System.out.println(intFunction.apply(512));//ToP Type Function은 출력을 P타입으로 한다.ToIntFunction<String>funcFour=(s)->s.length();// 4:21System.out.println(funcFour.applyAsInt("abcde"));// 출력이 P타입인 경우에는 AsP가 들어간다.!!!//ToIntBiFunction<String,String>// int 출력을 하는 Bi 함수// P: Int, Long, Double// int 에서 double로 바꾸는 함수 PToQFunction : P -> Q로 매핑하는 함수IntToDoubleFunctionfuncfive;// IntToIntFunction은 없다. 동일한 것에 대해서는 다른게 있다.}}
Operator 계열
입력받은 타입과 동일한 타입의 출력을 하는 함수형 인터페이스
Funtion 계열과 달리 입출력 타입이 다를 수 없다.
applyXXX() 메소드를 가지고 있고 매개값을 리턴값으로 매핑하는 역할보다는
매개값을 이용해서 연산을 수행한 후 동일한 타입으로 리턴값을 제공하는 역할을 한다.
importjava.util.function.BinaryOperator;importjava.util.function.IntBinaryOperator;importjava.util.function.IntUnaryOperator;importjava.util.function.UnaryOperator;publicclassMain{publicstaticvoidmain(String[]args){// 그냥 operator는 없다.// 입력이 1개 인 것을 Unary를 붙여서 표현UnaryOperator<String>operator=s->s+".";// 리턴타입을 따로 입력받지 않는다 입출력이 같으니깐System.out.println(operator.apply("왔다"));// apply() 사용.BinaryOperator<String>operator1=(s1,s2)->s1+s2;// 타입은 하나만 입력받게 되어있다. 출력은 동일한 타입이여야 하니깐?System.out.println(operator1.apply("나","왔다"));IntUnaryOperatorop=value->value*10;//타입을 받지 않는다 어차피 int입력 int출력이니System.out.println(op.applyAsInt(5));// LongUnaryOperator, DoubleUnaryOperatorIntBinaryOperatoribo=(v1,v2)->v1*v2;System.out.println(ibo.applyAsInt(10,20));//LongBinaryOperator, DoubleBinaryOperator}}
Leave a comment