자바

java.util.function 패키지

망재이 2023. 3. 11. 20:28

요즘 서블릿과 jsp를 공부하면서 느끼는건데 람다식에 대해서 자세히 잡아놔야할 것 같다. 자바스크립트를 완전 초반에 배웠다보니까 자바스크립트에서 사용했던 함수식이 기억이 잘 안나는데 람다식과 형태가 거의 똑같아서 람다식을 잘 잡아놓으면 JSFunction을 쓰는 것도 문제가 없을 것 같다.

 

  • java.uti.function 패키지에서 자주 쓰이는 인터페이스와 메소드에 대해서 알아보자
함수형 인터페이스 메소드 설명
java.lang.Runnable (Thread) void run() 매개변수도 없고, 반환값도 없음
Supplier<T> (공급자) void get() 매개변수는 없고, 반환값만 있음
Consumer<T> (소비자) void accept(T t) 매개변수만 있고, 반환값은 없음
Function<T R> R apply(T t) 일반적인 함수. 하나의 매개변수를 받아서 결과를 반환
Predicate<T> boolean test(T t) 조건식을 표현. 매개변수는 하나고 변환 타입은 boolean

 

  • 알아둘 것은 Predicate는 Function의 변형으로 반환타입이 boolean이라는 것이다. Predicate는 조건식을 람다식으로 표현하는데 사용
Predocate<String> isEmptyStr = s -> s.length()==0;
// s의 길이가 0이면 true
String s = "";

if(imEmptyStr.test(s))  //if(s.length()==0)
System.out.println("This is an empty String.");

 

  • 매개변수가 2개인 경우에도 인터페이스를 쓸 수 있는데 앞에 접두사 'Bi'가 붙음. Supplier는 매개변수가 없으므로 존재하지 않음
함수형 인터페이스 메소드 설명
BiConsumer<T, U> void accept(T t, U u) 두 개의 매개변수만 있고 반환값이 없음
BiPredicate<T, U> boolean test(T t,U u) 조건식을 표현하는데 사용. 매개변수는 둘, 반환값은 boolean
BiFunction<T, U, R> R apply(T t,U u) 두 개의 매개변수를 받아서 하나의 결과를 반환

 

  • 만약 3개 이상의 매개변수를 받고자 한다면 직접 만들어서 사용
@FunctionalInterface
interface TriFunction<T, U, V, R> {
	R apply(T t,U u,V v);
}

 

  • 만약 매개변수 타입과 반환타입의 타입이 모두 일치한다면 UnaryOperator, BinaryOperator를 사용할 수 있음
  • 매개변수가 두개라고 하더라도 타입이 하나이기 때문에 지네릭스를 하나만 써줌
함수형 인터페이스 메소드 설명
UnaryOperator<T> T apply(T t) 매개변수가 하나
BinaryOperator<T> T apply(T t, T t) 매개변수가 둘

 

[ 활용 ]

package java14;

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 JavaUtilFunction {

    public static void main(String[] args) {
        // 공급자 난수 만들기 (1~100)
        // 소비자 출력
        // 조건식 짝수
        // 함수 i의 일의 자리 없애기
        Supplier<Integer> s = () -> (int)(Math.random()*100) + 1;
        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<>();
        // 난수를 생성해서 list를 출력하고, 짝수만 걸러서 새로운 리스트에 넣어주고 새로운 리스트 출력
        makeRandomList(s,list);
        System.out.println(list);
        printEvenNum(p,c,list);
        List<Integer> newList = doSomething(f,list);
        System.out.println(newList);

    }

    static <T> List<T> doSomething(Function<T, T> f, List<T> list) {
        //i의 일의 자리를 없애고 newlist에 추가
        List<T> newList = new ArrayList<T>(list.size());

        for(T i:list) {
            newList.add(f.apply(i));
        }

        return newList;
    }

    static <T> void printEvenNum(Predicate <T> p,Consumer <T> c, List <T> list) {
        //짝수 출력
        for(T i:list) {
            if(p.test(i)) {
                c.accept(i);
            }
        }
        System.out.println();

    }

    static <T> void makeRandomList(Supplier<T> s, List<T> list) {
        //난수 생성 후 리스트 추가
        for(int i=0;i<10;i++) {
            list.add(s.get());
        }
    }
}
728x90