java - والاوبجكت - معادلات جافا من Func و Action




مقدمة الدورة و مفهوم الكائنات في البرمجة (4)

الأناقة من المفوضين Func overloaded (بالإضافة إلى المفوض مقابل مشكلة فئة المجهول) هي أنها تدعم من وسائط 0 إلى 16 ( Func<TResult> ، Func<T, TResult> ، Func<T1, T2, TResult> ، إلخ.)

لسوء الحظ ، هذا مستحيل في Java بسبب محو النوع. لا يمكن أن تختلف الفصول حسب المعلمات النوعية وحدها.

تجلب Java 8 الآن حديقة حيوانات من الأسماء مثل BiConsumer for Action<T, T2> و ، لأن Java لا تسمح باستخدام وسيطات الكتابة البدائية BiIntConsumer . "حديقة الحيوانات" ليست كبيرة جداً ، ولست على علم بوجود مكتبة توسعها. كان هناك اقتراح رائع لنوع الدالة الحرفية مثل (int, int) => void ولكن لم يتم اعتماده.

ما هي معادلات جافا من Func و Action ؟

أعني ، بدلاً من كتابة هذا بمفردي:

public interface Func<TInput, TResult>
{
    TResult call(TInput target) throws Exception;
}
public interface Action<T>
{
    void call(T target) throws Exception;
}

تشبه الواجهة Callable Func.

واجهة Runnable يشبه العمل.

بشكل عام ، تستخدم Java الفئات الداخلية المجهولة كبديل للمفوضين C #. على سبيل المثال ، هذه هي الطريقة التي تضيف بها رمزًا للرد على الزر اضغط في واجهة المستخدم الرسومية:

button.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) { 
          ...//code that reacts to the action... 
      }
});

حقا لا يوجد مكافئات لهؤلاء. يمكنك إنشاء فصول داخلية مجهولة في Java ، ولكن هناك بعض الواجهات المحددة بدلاً من تلك العامة مثل Func و Action.


في Java 8 ، المكافئات هي java.util.function.Function<T, R> و java.util.function.Consumer<T> interfaces بالترتيب. وبالمثل ، 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-like التي System.Linq.Enumerable.Select<TSource, TResult> هنا لا تكون System.Linq.Enumerable.Select<TSource, TResult> بشكل كامل مجموعات المصدر قبل إرجاع مجموعات النتائج إلى المتصل. ومع ذلك ، أجد أنها مفيدة لأغراض النحوية بحتة ويمكن جعل كسول إذا لزم الأمر. معطى

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




java