سؤال

أنا أبحث عن طريقة مجموعات Google التي تُرجع النتيجة الأولى لتسلسل الموردين الذين لا يعودون NULL.

كنت أبحث في استخدام teerables.find () ولكن في مسند بلدي ، سأضطر إلى الاتصال بمورد بلدي لمقارنة النتيجة ضد NULL ، ثم يجب أن أتصل بها مرة أخرى بمجرد إعادة طريقة البحث عن المورد.

هل كانت مفيدة؟

المحلول

بالنظر إلى تعليقك لتهدئة إجابة Storm (الرغبة في عدم الاتصال Supplier.get() مرتين) ، ثم ماذا عن:

private static final Function<Supplier<X>, X> SUPPLY = new Function<....>() {
    public X apply(Supplier<X> in) {
        // If you will never have a null Supplier, you can skip the test;
        // otherwise, null Supplier will be treated same as one that returns null
        // from get(), i.e. skipped
        return (in == null) ? null : in.get();
    }
}

ومن بعد

Iterable<Supplier<X>> suppliers = ... wherever this comes from ...

Iterable<X> supplied = Iterables.transform(suppliers, SUPPLY);

X first = Iterables.find(supplied, Predicates.notNull());

لاحظ أن الأمر الذي يخرج من Iterables.transform() تم تقييمه بتكاسل ، وبالتالي Iterables.find() الحلقات فوقها ، يمكنك تقييمها فقط بقدر أول غيرnull-العودة واحدة ، وهذا مرة واحدة فقط.

نصائح أخرى

لقد طلبت كيفية القيام بذلك باستخدام مجموعات Google ، ولكن إليك كيفية القيام بذلك دون استخدام مجموعات Google. قارنها بإجابة Cowan (ما هي إجابة جيدة) - أيهما أسهل في الفهم؟

private static Thing findThing(List<Supplier<Thing>> thingSuppliers) {
  for (Supplier<Thing> supplier : thingSuppliers) {
    Thing thing = supplier.get();
    if (thing != null) {
      return thing;
    }
  }
  // throw exception or return null
}

بدلاً من التعليق - إذا كان هذا هو خطأ المتصل في صفك ، فأرمي غير شرعي أو غير قانوني أو غير قانوني حسب الاقتضاء ؛ إذا لم يكن هذا قد حدث من قبل ، استخدم AssertionError ؛ إذا كان هذا أمرًا طبيعيًا ، فإن الكود الذي يستدعي هذا يتوقع التحقق من ذلك ، فيمكنك إعادة NULL.

ما هو الخطأ في هذا؟

List<Supplier> supplierList = //somehow get the list
Supplier s = Iterables.find(supplierList, new Predicate<Supplier>(){
     boolean apply(Supplier supplier) {
         return supplier.isSomeMethodCall() == null;
     }
     boolean equals(Object o) {
         return false;
     }
});

هل تحاول حفظ بعض الخطوط؟ التحسين الوحيد الذي يمكن أن أفكر فيه هو استيراد الاكتشاف الثابت حتى تتمكن من التخلص من "Teerables". كما أن المسند هو فئة داخلية مجهولة ، إذا كنت في حاجة إليها في أكثر من مكان يمكنك إنشاء فصل دراسي وسيبدو ، سيبدو ،

List<Supplier> supplierList = //somehow get the list
Supplier s = find(supplierList, new SupplierPredicateFinder());

حيث المورد predicatefinder هو فئة أخرى.

تحديث: في هذه الحالة ، تجد الطريقة الخاطئة. تحتاج فعليًا إلى وظيفة مخصصة مثل هذه يمكن أن تُرجع قيمتين. إذا كنت تستخدم Commons-Collections ، فيمكنك استخدام DefaultMapentry أو يمكنك ببساطة إرجاع كائن [2] أو خريطة.

public static DefaultMapEntry getSupplier(List<Supplier> list) {
    for(Supplier s : list) {
        Object heavyObject = s.invokeCostlyMethod();
        if(heavyObject != null) {
             return new DefaultMapEntry(s, heavyObject);
        }
    }
}

استبدل DefaultMapentry بقائمة من الحجم 2 أو hashmap بحجم 1 أو مجموعة من الطول 2 :)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top