자바 람다에 둘 이상의 매개 변수가있을 수 있습니까?


162

Java에서 람다가 여러 다른 유형을 허용하도록 할 수 있습니까?

즉 : 단일 변수가 작동합니다.

    Function <Integer, Integer> adder = i -> i + 1;
    System.out.println (adder.apply (10));

Varargs도 작동합니다.

    Function <Integer [], Integer> multiAdder = ints -> {
        int sum = 0;
        for (Integer i : ints) {
            sum += i;
        }
        return sum;
    };

    //.... 
    System.out.println ((multiAdder.apply (new Integer [] { 1, 2, 3, 4 })));

하지만 저는 다음과 같이 다양한 유형의 인수를 받아 들일 수있는 것을 원합니다.

    Function <String, Integer, Double, Person, String> myLambda = a , b, c, d->  {
    [DO STUFF]
    return "done stuff"
    };

주요 용도는 편의를 위해 함수 내부에 작은 인라인 함수를 포함하는 것입니다.

Google을 둘러보고 Java의 Function Package를 검사했지만 찾을 수 없습니다. 이것이 가능한가?

답변:


185

여러 유형 매개 변수로 이러한 기능 인터페이스를 정의하면 가능합니다. 그런 내장 유형이 없습니다. (여러 매개 변수가있는 몇 가지 제한된 유형이 있습니다.)

@FunctionalInterface
interface Function6<One, Two, Three, Four, Five, Six> {
    public Six apply(One one, Two two, Three three, Four four, Five five);
}

public static void main(String[] args) throws Exception {
    Function6<String, Integer, Double, Void, List<Float>, Character> func = (a, b, c, d, e) -> 'z';
}

나는 그것을 Function6여기에서 불렀다 . 이름은 사용자의 재량에 달려 있습니다. Java 라이브러리의 기존 이름과 충돌하지 않도록하십시오.


요청한 것이면 가변 개수의 유형 매개 변수를 정의 할 방법도 없습니다.


Scala와 같은 일부 언어는 1, 2, 3, 4, 5, 6 등의 유형 매개 변수를 사용하여 이러한 유형에 내장 된 여러 유형을 정의합니다.


61
언제든지 Currying을 사용할 수 있습니다.Function<One, Function<Two, Function<Three, Function<Four, Function<Five, Six>>>>> func = a -> b -> c -> d -> e -> 'z';
Holger

@SotiriosDelimanolis : 차라리 초보자들에게는 불분명 할 수 Function있는 충돌 하는 다른 이름을 선택하고 싶습니다 java.util.function.Function<T,R>.
Nikolas Charalambidis

@Nikolas 합리적입니다. 편집.
Sotirios Delimanolis

41

2 개의 매개 변수가있는 경우 BiFunction. 더 필요한 경우 다음과 같이 고유 한 함수 인터페이스를 정의 할 수 있습니다.

@FunctionalInterface
public interface FourParameterFunction<T, U, V, W, R> {
    public R apply(T t, U u, V v, W w);
}

매개 변수가 두 개 이상인 경우 다음과 같이 인수 목록을 괄호로 묶어야합니다.

FourParameterFunction<String, Integer, Double, Person, String> myLambda = (a, b, c, d) -> {
    // do something
    return "done something";
};

36

이 경우 기본 라이브러리 (java 1.8)의 인터페이스를 사용할 수 있습니다.

java.util.function.BiConsumer
java.util.function.BiFunction

인터페이스에 기본 메소드의 작은 (최고가 아닌) 예가 있습니다.

default BiFunction<File, String, String> getFolderFileReader() {
    return (directory, fileName) -> {
        try {
            return FileUtils.readFile(directory, fileName);
        } catch (IOException e) {
            LOG.error("Unable to read file {} in {}.", fileName, directory.getAbsolutePath(), e);
        }
        return "";
    };
}}

5
이러한 인터페이스를 사용하여 요구 사항을 충족하는 방법을 설명하기 위해 질문을 수정하면 Java8 팬으로부터 더 많은 찬성 투표를 받게됩니다.
Martin Cowie

3
BiFunction 당신이 두 개의 인수 함수를 정의 할 수 있습니다, 문제는 인수의 수와 기능에 관한 것입니다
드미트리 Klochkov

9

람다를 사용하려면 다음과 같은 세 가지 유형의 작업이 있습니다.
1. 매개 변수 수락-> 소비자
2. 테스트 매개 변수 반환 부울-> 조건 자
3. 매개 변수 및 반환 값 조작-> 함수

Java 기능 인터페이스 최대 2 개의 매개 변수 :
단일 매개 변수 인터페이스
Consumer
Predicate
함수

2 개 매개 변수 인터페이스
BiConsumer
BiPredicate
BiFunction

2 개 이상인 경우 다음과 같이 기능 인터페이스를 생성해야합니다 (소비자 유형) :

@FunctionalInterface
public interface FiveParameterConsumer<T, U, V, W, X> {
    public void accept(T t, U u, V v, W w, X x);
}

완벽한 대답!
Gaurav

1

이것이 특정 문제에 적용되는지 확실하지 않지만 일부에 적용 가능한 또 다른 대안 UnaryOperator은 java.util.function 라이브러리에서 사용하는 것 입니다. 지정한 동일한 유형을 반환하므로 모든 변수를 하나의 클래스에 넣고 매개 변수로 사용합니다.

public class FunctionsLibraryUse {

    public static void main(String[] args){
        UnaryOperator<People> personsBirthday = (p) ->{
            System.out.println("it's " + p.getName() + " birthday!");
            p.setAge(p.getAge() + 1);
            return p;
        };
        People mel = new People();
        mel.setName("mel");
        mel.setAge(27);
        mel = personsBirthday.apply(mel);
        System.out.println("he is now : " + mel.getAge());

    }
}
class People{
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

따라서이 경우 가지고있는 클래스 Person는 수많은 인스턴스 변수를 가질 수 있으며 람다 식의 매개 변수를 변경할 필요가 없습니다.

관심있는 사람들을 위해 java.util.function 라이브러리 사용 방법에 대한 메모를 작성했습니다. http://sysdotoutdotprint.com/index.php/2017/04/28/java-util-function-library/


1

또한 jOOL 라이브러리를 사용할 수 있습니다 - https://github.com/jOOQ/jOOL

이미 다른 수의 매개 변수로 기능 인터페이스를 준비했습니다. 예를 들어, 당신은 사용할 수 org.jooq.lambda.function.Function3에서 등 Function0까지 Function16.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.