JAVA4_02_function패키지

charl hi·2021년 10월 5일
0

JAVA4

목록 보기
2/13

링크텍스트

java.util.function 패키지

  • 자주 사용되는 다양한 함수형 인터페이스를 제공

매개변수 하나인 함수형 인터페이스

1. Supplier<T>

  • 반환만
@FunctionalInterface
public interface Supplier<T>{
	T get();
}

예)

Supplier<String> supplier = () -> "Hello World!";
System.out.println(supplier.get());
//Hello World!


2. Consumer<T>

  • 매개변수만
@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);

    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

andThen()

  • 하나의 함수가 끝난 후 다음 Consumer를 연쇄적으로 이용할 수 있다.
  • andThen'()' 요걸 나중에!

예)

Consumer<String> consumer = (str) -> System.out.println(str.split(" ")[0]);
consumer.accept("Hello World");	
//Hello
consumer.andThen(System.out::println).accept("Hello World");
//Hello
//Hello World
  • 먼저 accept()로 받아들인 Consumer를 먼저 처리하고
  • andThen()으로 받은 두번째 Consumer를 처리한다.
  • 👀왜 [0]?? : "Hello World"라는 문자열 하나만 받았기에
  • ✨✨accept()로 문자열을 분할했어도, 원본의 데이터는 유지된다.
    -> 👀👀왜?? : 함수형에서 함수는 값의 대입 또는 변경 등이 없기 때문에!!


3. Function<T, R>

@FunctionalInterface 
public interface Function<T, R> { 
	R apply(T t); 

	default <V> Function<V, R> compose(Function<? super V, ? extends T> before) { 
	Objects.requireNonNull(before); 
	return (V v) -> apply(before.apply(v)); 
} 

default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) { 
	Objects.requireNonNull(after); 
	return (T t) -> after.apply(apply(t)); 
} 

static <T> Function<T, T> identity() { return t -> t; } 
}

andThen()

  • 하나의 함수가 끝난 후 다음 Consumer를 연쇄적으로 이용할 수 있다.
  • andThen'()' 요걸 나중에!

compose()

  • 첫번째 함수 실행 이전에 먼저 함수를 실행하여 연쇄적으로 연결해준다.
  • compose'()' 요걸 먼저!!

static identity()

  • 자기 자신을 반환하는 static함수

예)

Function<String, Integer> function = str -> str.length();
function.apply("Hello World");
//암것도 안나옴...
System.out.println(function.apply("Hello World"));
//11


4. Predicate<T>

@FunctionalInterface
public interface Predicate<T> {

    boolean test(T t);

    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    default Predicate<T> negate() {
        return (t) -> !test(t);
    }

    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }

    @SuppressWarnings("unchecked")
    static <T> Predicate<T> not(Predicate<? super T> target) {
        Objects.requireNonNull(target);
        return (Predicate<T>)target.negate();
    }
}

예)

	Predicate<String> predicate = (str) -> str.equals("Hello World");
	System.out.println(predicate.test("Hell"));		//false
	System.out.println(predicate.test("Hello"));	//false
	System.out.println(predicate.test("Hello World"));	//true

출처

Predicate의 사용법

  • ✨✨원래 Predicate<T,R>이지만, 반환타입이 항상 Boolean이기 때문에 뒤는 쓰지 않는다.
    -> Predicate<T>


Quiz.

아래의 빈칸에 알맞은 함수형 인터페이스를 적으시오.

Supplier<Integer>
Consumer<Integer>
Predicate<Integer>
Function<Integer, Integer>



매개변수가 2개인 함수형 인터페이스(Bi~)



매개변수 3개라면? 직접 정의한다.



(매개변수 타입==반환 타입) 일치하는 함수형인페

  • 단항연산자, 이항연산자
  • 타입이 같기 때문에 <T> 하나!



ex14_02_1

링크텍스트

참고

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class Ex14_02_1 {

	public static void main(String[] args) {
		Supplier<Integer> s = () -> (int)(Math.random()*100)+1;	//1<=x<101
		Consumer<Integer> c = i -> System.out.print(i+", ");	//출력
		Predicate<Integer> p = i -> i%2==0;	//짝수인지 검사
		Function<Integer, Integer> f = i -> i/10*10;	//**일의 자리 없애기
		
		List<Integer> list = new ArrayList<>();
		makeRandomList(s, list);
		System.out.println(list);
		
		printEvenNum(p, c, list);
		
		List<Integer> list2 = eraseIll(f, list);
		System.out.println(list2);
		
	}
	
	//Supplier s를 받아(1~100 난수를 받아) list에 추가
	static <T> void makeRandomList(Supplier<T> s, List<T> list) {
		for(int i=0; i<10; i++)
			list.add(s.get());
	}
	
	//list를 받아 Predicate p로 짝수인지 검사하고, Consumer c로 출력
	static <T> void printEvenNum(Predicate<T> p, Consumer<T> c, List<T> list) {
		System.out.print("[");
		for(T i : list) {	//**list의 모든요소 하나하나를 Integer i에 넣어서 
			if(p.test(i))	//i가 짝수면 true, 홀수면 false
				c.accept(i);//짝수면 Consumer 람다식대로 출력
		}
		System.out.println("]");
	}
	
	//list와 같은 크기의 새 List를 만들어, Function f로 일의 자리 없애고 그 새 List에 저장
	static <T> List<T> eraseIll(Function<T, T> f, List<T> list) {
		List<T> newList = new ArrayList<T>(list.size());	//new ArrayList<T>(크기)
		for(T i : list)
			newList.add(f.apply(i));	//일의 자리를 없애서 새 newList에 저장
		return newList;	//그 newList 반환, [요소1, 요소2, ...]
		
	}
}

[99, 2, 69, 89, 7, 83, 63, 50, 42, 20]
[2, 50, 42, 20, ]
[90, 0, 60, 80, 0, 80, 60, 50, 40, 20]



Ref

0개의 댓글