Sebagai programmer non-Java yang mempelajari Java, saya membaca tentang Supplier
dan Consumer
antarmuka saat ini. Dan saya tidak bisa memahami penggunaan dan maknanya. Kapan dan mengapa Anda akan menggunakan antarmuka ini? Dapatkah seseorang memberi saya contoh orang awam yang sederhana tentang ini… Saya menemukan contoh Doc tidak cukup ringkas untuk pemahaman saya.
103
Consumer
danSupplier
Anda juga dapat mencari tutorial untukConsumer
…Jawaban:
Ini adalah Pemasok:
public Integer getInteger() { return new Random().nextInt(); }
Ini Konsumen:
public void sum(Integer a, Integer b) { System.out.println(a + b); }
Jadi dalam istilah awam, pemasok adalah metode yang mengembalikan beberapa nilai (seperti dalam nilai pengembaliannya). Padahal, konsumen adalah metode yang mengkonsumsi beberapa nilai (seperti dalam argumen metode), dan melakukan beberapa operasi padanya.
Itu akan berubah menjadi seperti ini:
// 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);
Adapun penggunaan, contoh yang paling mendasar adalah:
Stream#forEach(Consumer)
metode. Dibutuhkan Konsumen, yang mengkonsumsi elemen dari arus yang Anda iterasi, dan melakukan beberapa tindakan pada masing-masingnya. Mungkin mencetaknya.Consumer<String> stringConsumer = (s) -> System.out.println(s.length()); Arrays.asList("ab", "abc", "a", "abcd").stream().forEach(stringConsumer);
sumber
Alasan Anda mengalami kesulitan dalam memahami arti antarmuka fungsional seperti yang ada di dalamnya
java.util.function
adalah karena antarmuka yang ditentukan di sini tidak memiliki arti! Mereka hadir terutama untuk mewakili struktur , bukan semantik .Ini tidak umum untuk sebagian besar Java API. Java API yang khas, seperti kelas atau antarmuka, memiliki arti, dan Anda dapat mengembangkan model mental untuk apa yang diwakilinya dan menggunakannya untuk memahami operasi di dalamnya. Pertimbangkan
java.util.List
misalnya. AList
adalah wadah benda lain. Mereka memiliki urutan dan indeks. Jumlah objek yang terdapat dalam daftar dikembalikan olehsize()
. Setiap objek memiliki indeks dalam kisaran 0..size-1 (inklusif). Objek pada indeks i dapat diambil dengan memanggillist.get(i)
. Dan seterusnya.Antarmuka fungsional
java.util.function
tidak memiliki arti seperti itu. Sebaliknya, mereka adalah antarmuka yang hanya mewakili struktur suatu fungsi, seperti jumlah argumen, jumlah nilai yang dikembalikan, dan (terkadang) apakah argumen atau nilai yang dikembalikan adalah primitif. Dengan demikian kita memiliki sesuatu sepertiFunction<T,R>
yang merupakan fungsi yang mengambil satu argumen tipe T dan mengembalikan nilai tipe R . Itu dia. Apa fungsi itu? Yah, itu bisa melakukan apa saja ... selama itu membutuhkan satu argumen dan mengembalikan satu nilai. Itulah mengapa spesifikasi untukFunction<T,R>
tidak lebih dari "Merupakan fungsi yang menerima satu argumen dan menghasilkan hasil."Jelasnya, ketika kita menulis kode, itu memiliki makna, dan makna itu harus datang dari suatu tempat. Dalam kasus antarmuka fungsional, artinya berasal dari konteks di mana mereka digunakan. Antarmuka
Function<T,R>
tidak memiliki arti dalam isolasi. Namun, dijava.util.Map<K,V>
API, ada yang berikut ini:V computeIfAbsent(K key, Function<K,V> mappingFunction)
(karakter pengganti dieliminasi untuk singkatnya)
Ah, penggunaan
Function
ini sebagai "fungsi pemetaan". Apa fungsinya? Dalam konteks ini, jikakey
belum ada di peta, fungsi pemetaan dipanggil dan diberikan kunci dan diharapkan menghasilkan nilai, dan pasangan kunci-nilai yang dihasilkan dimasukkan ke dalam peta.Jadi, Anda tidak dapat melihat spesifikasi untuk
Function
(atau antarmuka fungsional lainnya, dalam hal ini) dan mencoba memahami apa artinya. Anda harus melihat di mana mereka digunakan di API lain untuk memahami apa artinya, dan arti itu hanya berlaku untuk konteks itu.sumber
A
Supplier
adalah metode apa pun yang tidak membutuhkan argumen dan mengembalikan nilai. Tugasnya secara harfiah adalah menyediakan contoh kelas yang diharapkan. Misalnya, setiap referensi ke metode 'pengambil' adalah aSupplier
public Integer getCount(){ return this.count; }
Referensi metode instance-nya
myClass::getCount
adalah instance dariSupplier<Integer>
.A
Consumer
adalah metode apa pun yang mengambil argumen dan tidak mengembalikan apa pun. Itu dipanggil untuk efek sampingnya. Dalam istilah Java, aConsumer
adalah ungkapan untukvoid
metode. Metode 'penyetel' adalah contoh yang bagus:public void setCount(int count){ this.count = count; }
Referensi metode instance-nya
myClass::setCount
adalah instance dariConsumer<Integer>
danIntConsumer
.A
Function<A,B>
adalah metode apa pun yang mengambil argumen dari satu tipe, dan mengembalikan tipe lain. Ini bisa disebut sebagai 'transformasi'. TheFunction<A,B>
mengambilA
dan mengembalikanB
. Penting untuk diperhatikan bahwa untuk nilai tertentuA
, fungsi tersebut harus selalu mengembalikan nilai tertentuB
.A
danB
sebenarnya bisa berjenis sama, seperti berikut ini:public Integer addTwo(int i){ return i+2; }
Referensi metode instansinya
myClass:addTwo
adalah aFunction<Integer, Integer>
dan aToIntFunction<Integer>
.Referensi metode Kelas ke pengambil adalah contoh lain dari suatu fungsi.
public Integer getCount(){ return this.count; }
Referensi metode kelasnya
MyClass::getCount
adalah turunan dariFunction<MyClass,Integer>
danToIntFunction<MyClass>
.sumber
Mengapa Konsumen / Pemasok / antarmuka fungsional lainnya didefinisikan dalam paket java.util.function : Konsumen dan Pemasok adalah dua, di antara banyak, antarmuka fungsional bawaan yang disediakan di Java 8. Tujuan dari semua antarmuka fungsional bawaan ini adalah untuk menyediakan "template" yang siap untuk antarmuka fungsional yang memiliki deskriptor fungsi umum (tanda tangan / definisi metode fungsional).
Katakanlah kita memiliki kebutuhan untuk mengubah tipe T ke tipe lain R. Jika kita melewatkan fungsi apa pun yang didefinisikan seperti ini sebagai parameter ke suatu metode, maka metode itu perlu mendefinisikan Antarmuka Fungsional yang metode fungsional / abstraknya mengambil parameter dari tipe T sebagai input dan memberikan parameter tipe R sebagai output. Sekarang, mungkin ada banyak skenario seperti ini dan programmer akhirnya akan menentukan beberapa antarmuka fungsional untuk kebutuhan mereka. Untuk menghindari skenario semacam ini, mempermudah pemrograman & membawa standar umum dalam penggunaan antarmuka fungsional, satu set antarmuka fungsional bawaan seperti Predikat, Fungsi, Konsumen & Pemasok telah ditentukan.
Apa yang dilakukan Konsumen : Antarmuka fungsional konsumen menerima masukan, melakukan sesuatu dengan masukan tersebut dan tidak memberikan keluaran apa pun. Definisinya seperti ini (dari Sumber Java) -
@FunctionalInterface public interface Consumer<T> { void accept(T t); }
Di sini accept () adalah metode fungsional \ abstrak yang tidak mengambil masukan dan tidak mengembalikan keluaran. Jadi, jika Anda ingin memasukkan Integer, lakukan sesuatu dengannya tanpa output, alih-alih menentukan antarmuka Anda sendiri, gunakan instance Consumer.
Apa yang dilakukan Pemasok : Antarmuka fungsional pemasok tidak menerima masukan apa pun tetapi mengembalikan satu keluaran. Ini didefinisikan seperti ini (dari Sumber Java) -
@FunctionalInterface public interface Supplier<T> { T get(); }
Di mana pun Anda membutuhkan fungsi yang mengembalikan sesuatu, katakanlah Integer, tetapi tidak mengambil keluaran, gunakan contoh Pemasok.
Jika lebih jelas, bersama dengan contoh penggunaan, antarmuka Konsumen & Pemasok diperlukan maka Anda dapat merujuk posting blog saya di tempat yang sama - http://www.javabrahman.com/java-8/java-8-java-util- fungsi-konsumen-tutorial-dengan-contoh / dan http://www.javabrahman.com/java-8/java-8-java-util-function-supplier-tutorial-with-examples/
sumber
1. Arti
Lihat jawaban saya atas pertanyaan saya di sini dan juga pertanyaan lain di sini , tetapi singkatnya Antarmuka baru ini memberikan konvensi dan deskripsi untuk digunakan semua orang (+ rangkaian metode yang funky seperti
.forEach(someMethod().andThen(otherMethod()))
2. Perbedaan
Konsumen : Mengambil sesuatu, melakukan sesuatu, tidak mengembalikan apa-apa:
void accept(T t)
Pemasok: Tidak mengambil apa-apa, mengembalikan sesuatu:
T get()
(kebalikan dari Konsumen, pada dasarnya metode 'pengambil' universal)3. Penggunaan
// Consumer: It takes something (a String) and does something (prints it) List<Person> personList = getPersons(); personList.stream() .map(Person::getName) .forEach(System.out::println);
Pemasok: membungkus kode berulang, misalnya waktu eksekusi kode
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; } }
sumber
Dalam istilah Laymen,
pemasok akan memasok data tetapi tanpa mengonsumsi data apa pun. Dalam istilah pemrograman, metode yang tidak mengambil argumen apa pun tetapi mengembalikan nilai. Ini digunakan untuk menghasilkan nilai baru.
http://codedestine.com/java-8-supplier-interface/
konsumen akan mengkonsumsi data dan tidak mengembalikan data apapun. Dalam istilah pemrograman, metode yang mengambil banyak argumen dan tidak mengembalikan nilai apa pun.
http://codedestine.com/java-8-consumer-interface/
sumber
Konsumen dan pemasok adalah antarmuka yang disediakan oleh java. Konsumen digunakan untuk iterasi atas elemen daftar dan pemasok digunakan untuk objek suplai
Anda dapat dengan mudah memahami dengan demonstrasi kode.
Konsumen
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); } }
Pemasok
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()); } }
sumber
Jawaban paling sederhana bisa jadi:
Konsumen dapat dipandang sebagai Fungsi <T, Void>. Pemasok dapat dipandang sebagai Fungsi <Void, T>.
sumber