जावा फंक और एक्शन के समकक्ष क्या हैं ?
मेरा मतलब है, अपने दम पर यह लिखने के बजाय:
public interface Func<TInput, TResult>
{
TResult call(TInput target) throws Exception;
}
public interface Action<T>
{
void call(T target) throws Exception;
}
जवाबों:
जावा 8 में, समतुल्य क्रमशः java.util.function.Function<T, R>और java.util.function.Consumer<T>इंटरफेस हैं। इसी तरह, java.util.function.Predicate<T>के बराबर है System.Predicate<T>। जैसा कि कहीं और उल्लेख किया गया है, ये प्रतिनिधियों के बजाय इंटरफेस हैं।
अलग से संबंधित: मैं वर्तमान में LINQ की तरह विस्तार विधि सामान करने के लिए निम्न उपयोगिता वर्ग पर बहुत अधिक झुकाव कर रहा हूं:
abstract class IterableUtil {
public static <T> Iterable<T> where(Iterable<T> items, Predicate<T> predicate) {
ArrayList<T> result = new ArrayList<T>();
for (T item : items) {
if (predicate.test(item)) {
result.add(item);
}
}
return result;
}
public static <T, R> Iterable<R> select(Iterable<T> items, Function<T, R> func) {
ArrayList<R> result = new ArrayList<R>();
for (T item : items) {
result.add(func.apply(item));
}
return result;
}
}
इसके विपरीत System.Linq.Enumerable.Where<TSource>और System.Linq.Enumerable.Select<TSource, TResult>मेरे द्वारा प्रस्तुत LINQ- जैसी विधियां आलसी नहीं हैं और कॉलर को परिणाम संग्रह वापस करने से पहले स्रोत संग्रह को पूरी तरह से पार कर लेते हैं। फिर भी, मैं उन्हें विशुद्ध रूप से वाक्यात्मक उद्देश्यों के लिए उपयोगी पाता हूं और यदि आवश्यक हो तो आलसी बनाया जा सकता है। दिया हुआ
class Widget {
public String name() { /* ... */ }
}
एक निम्नलिखित कर सकते हैं:
List<Widget> widgets = /* ... */;
Iterable<Widget> filteredWidgets = IterableUtil.where(widgets, w -> w.name().startsWith("some-prefix"));
जिसे मैं निम्नलिखित पसंद करता हूं:
List<Widget> widgets = /* ... */;
List<Widget> filteredWidgets = new ArrayList<Widget>();
for (Widget w : widgets) {
if (w.name().startsWith("some-prefix")) {
filteredWidgets.add(w);
}
}
कॉल करने योग्य इंटरफ़ेस फ़ंक के समान है।
रनने योग्य इंटरफ़ेस एक्शन के समान है।
सामान्य तौर पर, जावा सी # प्रतिनिधियों के प्रतिस्थापन के रूप में अनाम आंतरिक कक्षाओं का उपयोग करता है। उदाहरण के लिए यह है कि आप GUI में बटन प्रेस पर प्रतिक्रिया करने के लिए कोड कैसे जोड़ते हैं:
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
...//code that reacts to the action...
}
});
अतिभारित समारोह प्रतिनिधियों (डेलीगेट बनाम गुमनाम वर्ग मुद्दे के अलावा) की शान है कि वे 0 से 16 तर्क से समर्थन है ( Func<TResult>, Func<T, TResult>, Func<T1, T2, TResult>, आदि)
दुर्भाग्य से, प्रकार के क्षरण के कारण जावा में यह असंभव है। कक्षाएं केवल सामान्य प्रकार के मापदंडों से भिन्न नहीं हो सकती हैं।
जावा 8 अब जैसे नामों के एक चिड़ियाघर में लाता है BiConsumerके लिए Action<T, T2>, और, क्योंकि जावा आदिम प्रकार तर्क की अनुमति नहीं है BiIntConsumer। "चिड़ियाघर", हालांकि, बहुत बड़ा नहीं है, और मुझे एक पुस्तकालय के बारे में पता नहीं है जो इसे विस्तारित करता है। फ़ंक्शन प्रकार के शाब्दिक जैसे एक अद्भुत प्रस्ताव (int, int) => voidथा लेकिन इसे अपनाया नहीं गया था।
Func`1आदि। यह सिर्फ C # है जो उन लोगों को समान नाम देता है।
BiConsumerके लिए Action<T, T2>, और, क्योंकि जावा आदिम प्रकार पैरामीटर की अनुमति नहीं है BiIntConsumer। फ़ंक्शन प्रकार के शाब्दिक जैसे प्रस्ताव था, (int, int) => voidलेकिन इसे अपनाया नहीं गया था।
Func<T>उपयोग के लिए: java.util.function.Supplier
http://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html
SupplierFunc<T>(के विपरीत Func<T1, T2>) के बराबर होगा Action। एक Actionकोई तर्क स्वीकार करता है और कोई परिणाम देता है। (अन्य संस्करण Actionविभिन्न तर्कों को स्वीकार करते हैं और कोई परिणाम नहीं देते हैं।)
Func<T>जावा की तलाश कर रहा था और गलती से इसे याद कर लिया था Action<T>। उफ़
Action<>: 0 इनपुट, 0 आउटपुट। .andThen(...)कार्यक्षमता के साथ सबसे अच्छा ।
Action<>0 इनपुट और 0 आउटपुट के साथ है। लेकिन रीमर्बर, जावा में ये सिर्फ इंटरफेस हैं। तो, आप अपने खुद के उपयोग करने के लिए बना सकते हैं।
Runnableके लिए Action<>, हालांकि यह काफी के रूप में बहुत नया जावा 8 कार्यात्मक सामान के रूप में उपयोग करने के लिए नहीं है,।
जावा में प्रतिनिधियों की अवधारणा नहीं है। वर्कअराउंड अप्रोच के लिए, कृपया C # डेलीगेट्स पर एक जावा प्रोग्रामर लुक्स देखें :
जबकि C # में जावा के समान क्षमताओं का एक सेट है, इसने कई नई और दिलचस्प विशेषताएं जोड़ी हैं। प्रतिनिधिमंडल एक विधि को प्रथम श्रेणी की वस्तु के रूप में मानने की क्षमता है। एसी # डेलीगेट का उपयोग किया जाता है जहां जावा डेवलपर्स एक एकल विधि के साथ एक इंटरफेस का उपयोग करेंगे। इस लेख में, C # में प्रतिनिधियों के उपयोग पर चर्चा की गई है, और जावा डेलीगेट ऑब्जेक्ट के लिए कोड प्रस्तुत किया गया है जो एक समान कार्य कर सकता है। यहां सोर्स कोड डाउनलोड करें।
आप java.util का उपयोग कर सकते हैं। इस तरह से
Function<Employee, String> f0 = (e) -> e.toString();
लेकिन अगर आप इसे एक से अधिक तर्क के साथ उपयोग कर रहे हैं (जैसा कि C # Func है), तो आपने अपने संस्करण का कार्य FunctionalInterface के रूप में परिभाषित किया है।
@FunctionalInterface
public interface Func2Args<T, T1, R> {
R apply(T t, T1 t1);
}
@FunctionalInterface
public interface Func3Args<T,T1,T2,R> {
R apply(T t, T1 t1, T2 t2);
}
तब आप चर के साथ उपयोग कर सकते हैं तर्कों के नहीं
Func2Args<Employee,Employee,String> f2 = (e, e2) -> e.toString() +
e2.toString();
Func3Args<Employee,Employee,Employee,String> f3 = (e, e2, e3) ->
e.toString() + e2.toString() + e3.toString();
Java 8 से पुराने संस्करणों के लिए
C # में विधि कॉलबैक के लिए जिसका मैंने इस तरह उपयोग किया:
public void MyMethod(string par1, string par2, Action<int> callback, Action<int, string> callback2)
{
//Async Code
callback.invoke(1);
callback2.invoke(4, "str");
}
और इसे कॉल करना:
utils.MyMethod("par1", "par2", (i) =>
{
//cb result
}, (i, str) =>
{
//cb2 result
});
मैंने जावा में छोटे अमूर्त वर्ग बनाए हैं
package com.example.app.callbacks;
public abstract class Callback1<T> {
public void invoke(T obj) {}
}
package com.example.app.callbacks;
public abstract class Callback2<T, T2> {
public void invoke(T obj, T2 obj2) {}
}
package com.example.app.callbacks;
public abstract class Callback3<T, T2, T3> {
public void invoke(T obj, T2 obj2, T3 obj3) {}
}
...ETC
जावा विधि की तरह दिखता है:
public void myMethod(String par1, String par2, final Callback1<int> callback, final Callback2<int, String> callback2) {
//Async Code
callback.invoke(1);
callback2.invoke(4, "str");
}
अब इसे जावा में कॉल करते समय:
utils.myMethod("par1", "par2", new Callback<int>() {
@Override
public void invoke(int obj) {
super.invoke(obj);
//cb result
}
}, new Callback2<int, String>() {
@Override
public void invoke(int obj, String obj2) {
super.invoke(obj, obj2);
//cb2 result
}
});
यह आपके कॉलबैक को उन कक्षाओं में पास / सेट करके भी काम करता है, जिनमें आप उन्हें कॉल करना चाहते हैं, उसी तरीके का उपयोग इंटरफेसेस बनाने के लिए भी किया जा सकता है:
package com.example.app.interfaces;
public interface MyInterface<T> {
void makeDo(T obj);
void makeAnotherDo();
}