একটি জাভা ল্যাম্বডায় 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';
হোলার

@ সোতিরিওস ডেলিমনোলিস: আমি বরং একটি আলাদা নাম বেছে নেব 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
দ্বি ফাংশন আপনাকে কেবলমাত্র দুটি যুক্তিযুক্ত ফাংশনগুলি সংজ্ঞায়িত করতে দেয়, প্রশ্নটি বহু সংখ্যক যুক্তিযুক্ত ফাংশন সম্পর্কে
দিমিত্রি ক্লোচকভ

8

ল্যাম্বডা ব্যবহার করতে: তিন ধরণের অপারেশন রয়েছে:
১. পরামিতি গ্রহণ করুন -> গ্রাহক
২. পরীক্ষার প্যারামিটার রিটার্ন বুলিয়ান -> ভবিষ্যদ্বাণী
৩. পরামিতি এবং রিটার্নের মানটি পরিচালনা -> ফাংশন

দুই পরামিতি পর্যন্ত জাভা ক্রিয়াগত ইন্টারফেস:
ইন্টারফেস একক প্যারামিটার
কনজিউমার
সম্পৃক্ত
ফাংশন

ইন্টারফেস দুই প্যারামিটার
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

অন্য একটি বিকল্প, এটি আপনার নির্দিষ্ট সমস্যার ক্ষেত্রে প্রযোজ্য কিনা তা নিশ্চিত নয় তবে এটি UnaryOperatorজাভা.উটি.ল ফাংশন লাইব্রেরিতে ব্যবহার করা কিছু ক্ষেত্রে প্রযোজ্য । যেখানে এটি নির্দিষ্ট করা একই ধরণের ফিরে আসে, সুতরাং আপনি আপনার সমস্ত ভেরিয়েবলগুলি একটি শ্রেণিতে রেখেছেন এবং এটি পরামিতি হিসাবে রয়েছে:

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ইত্যাদি ব্যবহার করতে পারেন ।Function0Function16

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.