জাভা 8 সরবরাহকারী এবং ল্যাপারসনের জন্য গ্রাহক ব্যাখ্যা


103

জাভা নন জাভা প্রোগ্রামার হিসাবে আমি এই মুহুর্তে Supplierএবং Consumerইন্টারফেসগুলি সম্পর্কে পড়ছি । এবং আমি তাদের ব্যবহার এবং অর্থের চারপাশে আমার মাথা গুটিয়ে রাখতে পারি না। আপনি কখন এবং কেন এই ইন্টারফেস ব্যবহার করবেন? কেউ কি আমাকে এর একটি সহজ ল্যাপারসনের উদাহরণ দিতে পারেন ... আমি ডক উদাহরণগুলি বুঝতে পারি যা আমার বোঝার জন্য যথেষ্ট পরিমাণে সংহত নয়।


4
এপিআই ডক প্রতিটি পৃষ্ঠায় একটি লিঙ্ক শীর্ষে "ব্যবহার করুন" তোমার জন্য ক্লিক করতে পারেন যা লেবেল করেছে Consumerএবং Supplierএছাড়াও আপনি অনুসন্ধান করতে পারে টিউটোরিয়াল জন্য Consumer...
হোলগার

7
আমি স্টুয়ার্ট মার্কসের উত্তরটি পছন্দ করি। এবং আমি মনে করি নীচে উত্তর দেওয়া বেশিরভাগ লোকেরা বিষয়টিটি মিস করেছেন। সরবরাহকারী, গ্রাহক এবং কার্যাদি কীভাবে লিখবেন তা প্রশ্ন নয়। এটি বিশ্বের "কেন" আপনি চান করতে চান? এমন কোনও ব্যক্তির জন্য যা তাদের অভ্যস্ত নয়, তারা কোডটিকে আরও জটিল করে তোলে। তবে এগুলি ব্যবহার করে কী লাভ হবে তা পরিষ্কার নয়।
anton1980

আমি যতদূর দেখতে পাচ্ছি (এবং আমি আপনার হতাশাকে স্পর্শকাতর বর্ণনার সাথে ভাগ করে নিই) এটি কোডের কোনও টুকরোতে ব্যবহৃত কোনও অবজেক্ট থেকে অবজেক্ট-টাইপ এবং অবজেক্ট-ট্রিটমেন্ট উভয়ই বর্জন করার এক চতুর উপায়। এটি কেবলমাত্র নতুন নতুন ক্লাসগুলি সংজ্ঞায়িত করে এবং সরবরাহকারী এবং গ্রাহক ইন্টারফেসগুলিতে ইনজেকশনের মাধ্যমে বিভিন্ন ধরণের অবজেক্টে এই একই কোড প্রয়োগ করার অনুমতি দেয়। সুতরাং, পুলিশ রেকর্ড সিস্টেমে একই সন্দেহযুক্ত কোডটি সমস্ত সন্দেহভাজনদের জন্য ব্যবহৃত হয় তবে প্রত্যেকের জন্য চূড়ান্ত প্রিন্টআউট প্রতিটি সন্দেহভাজনের শ্রেণিবিন্যাসের উপর নির্ভর করে, যেমন 'নাগরিক', 'ক্ষুদ্র', 'লারেন্স', 'ফেলন', 'কঠোর', ইত্যাদি
ট্রাঙ্ক

উত্তর:


96

এটি সরবরাহকারী:

public Integer getInteger() {
    return new Random().nextInt();
}

এটি গ্রাহক:

public void sum(Integer a, Integer b) {
    System.out.println(a + b);
}

সুতরাং সাধারণ লোকের কথায়, সরবরাহকারী এমন একটি পদ্ধতি যা কিছু মান দেয় (এটির ফেরতের মান হিসাবে)। অন্যদিকে, ভোক্তা এমন একটি পদ্ধতি যা কিছু মান গ্রহণ করে (পদ্ধতি তর্ক হিসাবে), এবং সেগুলি কিছু পরিচালনা করে।

এগুলি এরকম কিছুতে রূপান্তরিত হবে:

// new operator itself is a supplier, of the reference to the newly created object
Supplier<List<String>> listSupplier = ArrayList::new;
Consumer<String> printConsumer = a1 -> System.out.println(a1);
BiConsumer<Integer, Integer> sumConsumer = (a1, a2) -> System.out.println(a1 + a2);

ব্যবহার হিসাবে, খুব প্রাথমিক উদাহরণ হতে হবে: Stream#forEach(Consumer)পদ্ধতি। এটি একটি গ্রাহক লাগে, যা আপনার পুনরুক্তি করা স্ট্রিমের উপাদানটি গ্রাস করে এবং সেগুলির প্রতিটিটিতে কিছু ক্রিয়া করে। সম্ভবত এগুলি মুদ্রণ করুন।

Consumer<String> stringConsumer = (s) -> System.out.println(s.length());
Arrays.asList("ab", "abc", "a", "abcd").stream().forEach(stringConsumer);

4
সুতরাং, সরবরাহকারী কোনও পদ্ধতির উদাহরণ তৈরির উপায় যা 'কিছু' ফেরত দেয়?
জেমস ইমানান

4
নিবন্ধন করুন এটি কোনও পদ্ধতির রেফারেন্স বা ল্যাম্বডা হতে পারে।
রোহিত জৈন

15
সরাসরি পদ্ধতিটি কল করার চেয়ে এর কী লাভ? এটি কি কারণ সরবরাহকারী কোনও মধ্যস্থির মতো কাজ করতে পারে এবং সেই "রিটার্ন" মানটি বন্ধ করতে পারে?
জেমস ইমানান

4
গ্রাহক <পূর্ণসংখ্যা, পূর্ণসংখ্যক> বৈধ নয়। গ্রাহকের একক ধরণের প্যারামিটার থাকে।
ন্যাসকার

4
তবে কেন এমন একটি নির্মাণ তৈরি? জাভাতে থাকার ফলে কোন সমস্যার সমাধান হয়?
ট্রাঙ্ক

179

যে কারণে কার্যকরী ইন্টারফেসের অর্থ বুঝতে আপনার অসুবিধা হচ্ছে তার কারণগুলি java.util.functionএখানে বর্ণিত ইন্টারফেসগুলির কোনও অর্থ হয় না! এগুলি মূলত কাঠামোর প্রতিনিধিত্ব করতে উপস্থিত রয়েছে , শব্দার্থক শব্দগুলি নয় ।

এটি বেশিরভাগ জাভা এপিআই-এর জন্য অতিক্রান্ত। সাধারণ জাভা এপিআই, যেমন শ্রেণি বা ইন্টারফেসের অর্থ রয়েছে এবং আপনি এটির জন্য একটি মানসিক মডেল বিকাশ করতে পারেন এবং এটির ক্রিয়াকলাপ বোঝার জন্য এটি ব্যবহার করতে পারেন। java.util.Listউদাহরণস্বরূপ বিবেচনা করুন । ক Listঅন্যান্য বস্তুর একটি ধারক। তাদের একটি ক্রম এবং একটি সূচক রয়েছে। তালিকায় থাকা অবজেক্টের সংখ্যা ফিরে আসে size()। প্রতিটি অবজেক্টের 0.. আকার -1 (অন্তর্ভুক্ত) ব্যাপ্তিতে একটি সূচক থাকে। ইনডেক্সের অবজেক্টটি আমি কল করে পুনরুদ্ধার করতে পারি list.get(i)। এবং তাই এগিয়ে।

কার্যকরী ইন্টারফেসের এর java.util.functionকোনও অর্থ নেই। পরিবর্তে, তারা এমন ইন্টারফেস যা কেবল কোনও ফাংশনের কাঠামোর প্রতিনিধিত্ব করে , যেমন আর্গুমেন্টের সংখ্যা, রিটার্ন মানগুলির সংখ্যা এবং (কখনও কখনও) কোনও যুক্তি বা রিটার্ন মান আদিম কিনা। সুতরাং আমাদের মতো এমন কিছু রয়েছে Function<T,R>যা একটি ফাংশনকে উপস্থাপন করে যা টাইপ টির একক যুক্তি নেয় এবং আর টাইপের মান দেয় । এটাই. এই ফাংশনটি কী করে? ঠিক আছে, এটি যে কোনও কিছু করতে পারে ... যতক্ষণ না এটি একক যুক্তি নেয় এবং একক মান দেয়। এ কারণেই স্পেসিফিকেশনটি Function<T,R>"এমন একটি কার্যকারিতা প্রতিনিধিত্ব করে যা একটি যুক্তি স্বীকার করে এবং ফলাফল উত্পন্ন করে"।

স্পষ্টতই, যখন আমরা কোড লিখছি, এর অর্থ রয়েছে এবং এর অর্থ কোথাও থেকে আসতে হবে। ক্রিয়ামূলক ইন্টারফেসের ক্ষেত্রে, অর্থটি ব্যবহার করা হচ্ছে সেই প্রসঙ্গে থেকেই আসে। ইন্টারফেসের Function<T,R>বিচ্ছিন্নতার কোনও অর্থ নেই। তবে, java.util.Map<K,V>এপিআইতে নিম্নলিখিতটি রয়েছে:

V computeIfAbsent(K key, Function<K,V> mappingFunction)

(বংশবৃদ্ধির জন্য ওয়াইল্ডকার্ড)

আহ, এই ব্যবহারটি Functionএকটি "ম্যাপিং ফাংশন" হিসাবে। এটা কি করে? এই প্রসঙ্গে, যদি keyইতিমধ্যে মানচিত্রে উপস্থিত না থাকে তবে ম্যাপিং ফাংশনটি কল করা হয় এবং কীটি হস্তান্তর করা হয় এবং একটি মান উৎপন্ন করার আশা করা হয়, এবং ফলস্বরূপ কী-মান জোড় মানচিত্রে প্রবেশ করানো হয়।

সুতরাং আপনি Function(বা অন্য কোনও ক্রিয়াকলাপের ইন্টারফেসের জন্য এই বিষয়ে) এর স্পেসিফিকেশনটি দেখতে পারবেন না এবং তাদের অর্থ কী তা বোঝার চেষ্টা করতে পারবেন না। তাদের অর্থ কী তা বোঝার জন্য আপনাকে অন্যান্য এপিআইগুলিতে কোথায় ব্যবহার করা হচ্ছে তা আপনাকে দেখতে হবে এবং এই অর্থটি কেবলমাত্র সেই প্রসঙ্গে প্রযোজ্য।


4
সুতরাং মূলত, এটি কেবল টাইপ হিসাবে কাজ করে
জ্যাক গুও

আর একটি দরকারী তথ্য হতে পারে যে কার্যকরী ইন্টারফেসে একাধিক বাস্তবায়িত পদ্ধতি থাকতে পারে যা আপনার
কোডগুলিতে

28

Supplierএমন কোনও পদ্ধতি যা কোনও আর্গুমেন্ট নেয় না এবং একটি মান দেয় returns এটির কাজটি একটি প্রত্যাশিত শ্রেণীর উদাহরণ সরবরাহ করা। উদাহরণস্বরূপ, একটি 'গেটর' পদ্ধতির প্রতিটি রেফারেন্স হ'ল কSupplier

public Integer getCount(){
    return this.count;
}

এর উদাহরণ পদ্ধতি রেফারেন্স myClass::getCountএকটি উদাহরণ Supplier<Integer>

Consumerএমন কোনও পদ্ধতি যা আর্গুমেন্ট গ্রহণ করে এবং কিছুই দেয় না। এটি এর পার্শ্ব প্রতিক্রিয়া জন্য অনুরোধ করা হয়। জাভা শর্তাবলী, একটি Consumerএকটি voidপদ্ধতির জন্য প্রতিমা । 'সেটার' পদ্ধতিগুলি একটি ভাল উদাহরণ:

public void setCount(int count){
    this.count = count;
}

এর উদাহরণ পদ্ধতির উল্লেখটি myClass::setCountএকটি উদাহরণ Consumer<Integer>এবং IntConsumer

Function<A,B>হ'ল এমন কোনও পদ্ধতি যা এক প্রকারের আর্গুমেন্ট গ্রহণ করে এবং অন্যটি দেয়। এটি একটি 'রূপান্তর' হিসাবে উল্লেখ করা যেতে পারে। Function<A,B>একটি সময় লাগে Aএবং একটি ফেরৎ B। উল্লেখযোগ্যটি হল যে প্রদত্ত মানের জন্য A, ফাংশনটি সর্বদা একটি নির্দিষ্ট মান প্রদান করে BAএবং Bপ্রকৃতপক্ষে নিম্নলিখিত ধরণের মতো একই ধরণের হতে পারে:

public Integer addTwo(int i){
    return i+2;
}

এর উদাহরণ পদ্ধতির রেফারেন্সটি myClass:addTwoa Function<Integer, Integer>এবং a ToIntFunction<Integer>

গেটারের কাছে ক্লাস পদ্ধতির উল্লেখ কোনও ফাংশনের অন্য উদাহরণ of

public Integer getCount(){
    return this.count;
}

এর ক্লাস পদ্ধতির রেফারেন্স MyClass::getCountএকটি উদাহরণ Function<MyClass,Integer>এবং ToIntFunction<MyClass>


15

Java.util.function প্যাকেজে কনজিউমার / সাপ্লায়ার / অন্যান্য কার্যকরী ইন্টারফেসগুলি কেন সংজ্ঞায়িত করা হয়েছে : জাভা 8 তে অন্তর্নির্মিত কার্যকরী ইন্টারফেসগুলির মধ্যে অনেকের মধ্যে গ্রাহক এবং সরবরাহকারী দুটি, এই বিল্ট ফাংশনাল ইন্টারফেসগুলির উদ্দেশ্য হ'ল সাধারণ ফাংশন বর্ণনাকারী (ক্রিয়ামূলক পদ্ধতিতে স্বাক্ষর / সংজ্ঞা) থাকার ক্রিয়ামূলক ইন্টারফেসের জন্য একটি "টেম্পলেট" সরবরাহ করতে।

ধরুন আমাদের একটি টাইপ টি কে অন্য টাইপ আর তে রূপান্তর করতে হবে। যদি আমাদের কোনও প্যারামিটার হিসাবে এরূপ সংজ্ঞায়িত কোনও ফাংশন কোনও পদ্ধতিতে পাস করতে হয় তবে সেই পদ্ধতিতে একটি ফাংশনাল ইন্টারফেস সংজ্ঞায়িত করতে হবে যার কার্যকরী / বিমূর্ত পদ্ধতিটি পরামিতি নেয় ইনপুট হিসাবে টি টাইপের এবং আউটপুট হিসাবে আর টাইপ আর এর একটি প্যারামিটার দেয়। এখন, এর মতো অনেক পরিস্থিতিতে থাকতে পারে এবং প্রোগ্রামার (গুলি) তাদের প্রয়োজনের জন্য একাধিক ক্রিয়ামূলক ইন্টারফেস সংজ্ঞায়িত করবে। এই জাতীয় পরিস্থিতি এড়াতে, প্রোগ্রামিং সহজ করুন এবং ক্রিয়ামূলক ইন্টারফেসের ব্যবহারের জন্য একটি সাধারণ মান আনুন, প্রিডিকেট, ফাংশন, কনজিউমার এবং সাপ্লায়ারের মতো অন্তর্নির্মিত কার্যকরী ইন্টারফেসগুলির একটি সেট সংজ্ঞায়িত করা হয়েছে।

কনজিউমার কী করে : কনজিউমার ফাংশনাল ইন্টারফেস একটি ইনপুট গ্রহণ করে, সেই ইনপুট দিয়ে কিছু করে এবং কোনও আউটপুট দেয় না। এর সংজ্ঞাটি এর মতো (জাভা উত্স থেকে) -

@FunctionalInterface
public interface Consumer<T> {
 void accept(T t);
}

এখানে গ্রহণ () হ'ল কার্যকরী st বিমূর্ত পদ্ধতি যা কোনও ইনপুট নেয় এবং কোনও আউটপুট দেয় না। সুতরাং, আপনি যদি কোনও পূর্ণসংখ্যাকে ইনপুট করতে চান, তবে কোনও আউটপুট ছাড়াই এটির সাথে কিছু করুন তারপরে আপনার নিজের ইন্টারফেসকে সংজ্ঞায়িত করার পরিবর্তে গ্রাহকের উদাহরণ ব্যবহার করুন।

সরবরাহকারী কী করে : সরবরাহকারী ফাংশনাল ইন্টারফেস কোনও ইনপুট নেয় না তবে ফলাফল দেয়। এটি এর মতো সংজ্ঞায়িত হয়েছে (জাভা উত্স থেকে) -

@FunctionalInterface
public interface Supplier<T> {
  T get();
}

আপনার যেখানেই কোনও ফাংশন প্রয়োজন যেখানে কিছু ফেরত দেয়, একটি পূর্ণসংখ্যা বলে, তবে কোনও আউটপুট সরবরাহকারীর উদাহরণ ব্যবহার করে না।

যদি গ্রাহক ও সরবরাহকারী ইন্টারফেসের উদাহরণস্বরূপ ব্যবহারের পাশাপাশি আরও স্পষ্টতা প্রয়োজন হয় তবে আপনি আমার ব্লগ পোস্টগুলিতে একই বিষয়ে উল্লেখ করতে পারেন - http://www.javabrahman.com/java-8/java-8-java-util- ফাংশন-কনজিউমার-টিউটোরিয়াল-সহ-উদাহরণগুলি এবং এবং http://www.javabrahman.com/java-8/java-8-java-util-function-supplier-tutorial- উইথ- উদাহরণসমূহ /


12

1. অর্থ

আমার প্রশ্নের আমার উত্তরগুলি এখানে এবং অন্য একটি এখানে দেখুন , তবে সংক্ষেপে এই নতুন ইন্টারফেসগুলি প্রত্যেককে ব্যবহারের জন্য কনভেনশন এবং বর্ণনামূলকতা সরবরাহ করে (+ ফানকি পদ্ধতিতে শৃঙ্খলাবদ্ধ যেমন.forEach(someMethod().andThen(otherMethod()))

2. পার্থক্য

গ্রাহক : কিছু নেয়, কিছু করে, কিছু দেয় না:void accept(T t)

সরবরাহকারী: কিছুই নেয় না, কিছু ফেরত দেয়: T get()(গ্রাহকের বিপরীতে, মূলত সর্বজনীন 'গেটর' পদ্ধতি)

3. ব্যবহার

// Consumer: It takes something (a String) and does something (prints it) 
    List<Person> personList = getPersons();

     personList.stream()
                    .map(Person::getName)    
                    .forEach(System.out::println); 

সরবরাহকারী: পুনরাবৃত্তি কোড মোড়ানো, উদাহরণস্বরূপ কোড সম্পাদন সময়

public class SupplierExample {

    public static void main(String[] args) {

        // Imagine a class Calculate with some methods
        Double result1 = timeMe(Calculate::doHeavyComputation);
        Double result2 = timeMe(Calculate::doMoreComputation);
    }
    private static Double timeMe(Supplier<Double> code) {

        Instant start = Instant.now();
        // Supplier method .get() just invokes whatever it is passed
        Double result = code.get();
        Instant end = Instant.now();

        Duration elapsed = Duration.between(start,end);
        System.out.println("Computation took:" + elapsed.toMillis());

        return result;
    }
}

0

লেমন শর্তাবলী,

সরবরাহকারী ডেটা সরবরাহ করবে তবে কোনও ডেটা গ্রাস না করে। প্রোগ্রামিংয়ের ভাষায় এমন একটি পদ্ধতি যা কোনও যুক্তি গ্রহণ করে না তবে মান দেয়। এটি নতুন মান তৈরি করতে ব্যবহৃত হয়।

http://codedestine.com/java-8-supplier-interface/

ভোক্তা ডেটা গ্রাস করবে কিন্তু কোনও ডেটা ফেরত দেবে না। প্রোগ্রামিংয়ের শর্তে এমন একটি পদ্ধতি যা একাধিক যুক্তি নেয় এবং কোনও মান দেয় না not

http://codedestine.com/java-8-cuumer-interface/


0

গ্রাহক এবং সরবরাহকারী হ'ল জাভা সরবরাহ করা ইন্টারফেস। গ্রাহক তালিকার উপাদানগুলির উপরে পুনরাবৃত্তির জন্য ব্যবহার করা হয় এবং সরবরাহকারী সরবরাহকারী বস্তুর জন্য ব্যবহার করা হয়

কোড প্রদর্শনের মাধ্যমে আপনি সহজেই বুঝতে পারবেন।

গ্রাহক

package com.java.java8;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

/**
 * The Class ConsumerDemo.
 *
 * @author Ankit Sood Apr 20, 2017
 */
public class ConsumerDemo {

    /**
     * The main method.
     *
     * @param args
     *            the arguments
     */
    public static void main(String[] args) {

    List<String> str = new ArrayList<>();
    str.add("DEMO");
    str.add("DEMO2");
    str.add("DEMO3");

    /* Consumer is use for iterate over the List */
    Consumer<String> consumer = new Consumer<String>() {
        @Override
        public void accept(String t) {

        /* Print list element on consile */
        System.out.println(t);
        }
    };

    str.forEach(consumer);

    }

}

সরবরাহকারী

package com.java.java8;

import java.util.function.Supplier;

/**
 * The Class SupplierDemo.
 *
 * @author Ankit Sood Apr 20, 2017
 */
public class SupplierDemo {

    /**
     * The main method.
     *
     * @param args
     *            the arguments
     */
    public static void main(String[] args) {
    getValue(() -> "Output1");
    getValue(() -> "OutPut2");
    }

    /**
     * Gets the value.
     *
     * @param supplier
     *            the supplier
     * @return the value
     */
    public static void getValue(Supplier<?> supplier) {
    System.out.println(supplier.get());
    }

}

0

সহজ উত্তর হতে পারে:

কোনও গ্রাহককে একটি ফাংশন <টি, অকার্যকর> হিসাবে দেখা যেতে পারে। সরবরাহকারীকে একটি ফাংশন <শূন্য, টি> হিসাবে দেখা যেতে পারে।

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