क्या एक जावा लैम्ब्डा में 1 से अधिक पैरामीटर हो सकते हैं?


157

जावा में, क्या एक लैम्ब्डा को कई अलग-अलग प्रकारों को स्वीकार करना संभव है?

यानी: एकल चर काम करता है:

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

वर्गर भी काम करते हैं:

    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"
    };

मुख्य उपयोग सुविधा के लिए कार्यों के अंदर छोटे इनलाइन कार्यों को करना है।

मैंने गूगल के चारों ओर देखा और जावा के फंक्शन पैकेज का निरीक्षण किया, लेकिन नहीं मिला। क्या यह संभव है?

जवाबों:


178

यह संभव है यदि आप ऐसे कार्यात्मक इंटरफ़ेस को कई प्रकार के मापदंडों के साथ परिभाषित करते हैं। इस प्रकार का कोई निर्मित नहीं है। (कई मापदंडों के साथ कुछ सीमित प्रकार हैं।)

@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यहां बुलाया है। नाम आपके विवेक पर है, बस जावा पुस्तकालयों में मौजूदा नामों के साथ संघर्ष न करने का प्रयास करें।


यदि आप के बारे में पूछ रहे थे, तो चर प्रकारों को परिभाषित करने का कोई तरीका नहीं है।


कुछ भाषाएं, जैसे स्काला, 1, 2, 3, 4, 5, 6, आदि प्रकारों में निर्मित कई प्रकारों को परिभाषित करती हैं।


58
आप हमेशा करी का उपयोग कर सकते हैं:Function<One, Function<Two, Function<Three, Function<Four, Function<Five, Six>>>>> func = a -> b -> c -> d -> e -> 'z';
Holger

@ सोतिरोसिलिमैनोलिस: मैं ऐसा कोई दूसरा नाम चुनूंगा, Functionजिसके साथ java.util.function.Function<T,R>होने वाली झड़पें शुरुआती लोगों के लिए अस्पष्ट हो सकती हैं।
निकोलस

@ निकोलस यह उचित है। संपादित।
सोतीरिओस डेलिमोनोलिस

39

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";
};

34

इस मामले के लिए आप डिफ़ॉल्ट लाइब्रेरी (जावा 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
आपको जावा 8 प्रशंसकों से अधिक अप-वोट मिलेंगे यदि आप अपने प्रश्न में संशोधन करते हैं कि आवश्यकता को पूरा करने के लिए उन इंटरफेस का उपयोग कैसे किया जा सकता है।
मार्टिन काउई

3
BiFunction आपको केवल दो-तर्क कार्यों को परिभाषित करने की अनुमति देता है, सवाल किसी भी तर्क के साथ कार्यों के बारे में है
दिमित्री क्लोचकोव

8

लैम्ब्डा का उपयोग करने के लिए: तीन प्रकार के ऑपरेशन होते हैं:
1. पैरामीटर स्वीकार करें -> उपभोक्ता
2. टेस्ट पैरामीटर रिटर्न बूलियन -> विधेय
3. पैरामीटर और वापसी मूल्य में हेरफेर -> फ़ंक्शन

दो पैरामीटर तक जावा कार्यात्मक इंटरफ़ेस:
इंटरफ़ेस एकल पैरामीटर
उपभोक्ता
विधेय
समारोह

इंटरफ़ेस दो पैरामीटर
BiConsumer
BiPredicate
BiFunction

दो से अधिक के लिए , आपको अनुसरण के रूप में कार्यात्मक इंटरफ़ेस बनाना होगा (उपभोक्ता प्रकार):

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

1

एक अन्य विकल्प, सुनिश्चित नहीं है कि यह आपकी विशेष समस्या पर लागू होता है लेकिन कुछ पर लागू हो सकता है यह UnaryOperatorjava.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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.