سؤال

أحتاج خريطة وظيفة.هل هناك شيء من هذا القبيل في جافا بالفعل ؟

(بالنسبة لأولئك الذين يتساءلون:أنا طبعا أعرف كيفية تنفيذ هذا تافهة وظيفة نفسي...)

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

المحلول

لا توجد فكرة عن وظيفة في JDK اعتبارًا من Java 6.

الجوافة لديه دور الواجهة على الرغم من
Collections2.transform(Collection<E>, Function<E,E2>)
توفر الطريقة الوظيفة التي تحتاجها.

مثال:

// example, converts a collection of integers to their
// hexadecimal string representations
final Collection<Integer> input = Arrays.asList(10, 20, 30, 40, 50);
final Collection<String> output =
    Collections2.transform(input, new Function<Integer, String>(){

        @Override
        public String apply(final Integer input){
            return Integer.toHexString(input.intValue());
        }
    });
System.out.println(output);

انتاج:

[a, 14, 1e, 28, 32]

في هذه الأيام ، مع Java 8 ، هناك بالفعل وظيفة خريطة ، لذلك ربما أكتب الرمز بطريقة أكثر إيجازًا:

Collection<String> hex = input.stream()
                              .map(Integer::toHexString)
                              .collect(Collectors::toList);

نصائح أخرى

منذ Java 8 ، هناك بعض الخيارات القياسية للقيام بذلك في JDK:

Collection<E> in = ...
Object[] mapped = in.stream().map(e -> doMap(e)).toArray();
// or
List<E> mapped = in.stream().map(e -> doMap(e)).collect(Collectors.toList());

نرى java.util.Collection.stream() و java.util.stream.Collectors.toList().

هناك مكتبة رائعة تسمى جافا الوظيفية الذي يتعامل مع العديد من الأشياء التي تريد أن تتمتع بها جافا ولكنها لا. ثم مرة أخرى ، هناك أيضًا هذه اللغة الرائعة التي تفعل كل ما كان يجب على جافا فعله ولكن لا يزال متوافقًا مع أي شيء مكتوب لـ JVM.

كن حذرا جدا مع Collections2.transform() من الجوافة.هذا الأسلوب هو أكبر ميزة هي أيضا أكبر خطر:لها الكسل.

نظرة على وثائق Lists.transform(), الذي أعتقد أنه ينطبق أيضا على Collections2.transform():

وظيفة يطبق بتكاسل استدعاؤها عند الحاجة.وهذا أمر ضروري من أجل إرجاع قائمة عرض ، ولكن هذا يعني أن وظيفة سيتم تطبيق مرات عديدة لمعظم العمليات مثل قائمة.يحتوي على(جافا.لانغ.كائن) قائمة.hashCode().هذا أداء جيدا ، وظيفة يجب أن تكون سريعة.لتجنب كسول عندما التقييم عاد القائمة لا تحتاج إلى أن يكون عرض نسخ القائمة التي تم إرجاعها في قائمة جديدة من اختيارك.

أيضا في وثائق Collections2.transform() يذكرون تحصل على عرض لايف, أن التغيير في القائمة المصدر تؤثر على تحويل قائمة.هذا النوع من السلوك يمكن أن يؤدي إلى صعوبة تتبع المشاكل إذا كان المطور لا يدرك الطريقة التي يعمل بها.

إذا كنت ترغب في مزيد من الكلاسيكية "الخريطة" ، أنه سيتم تشغيل مرة واحدة ومرة واحدة فقط, ثم كنت أفضل حالا مع FluentIterable, أيضا من الجوافة ، وهي العملية التي هي أبسط بكثير.هنا هو جوجل على سبيل المثال على ذلك:

FluentIterable
       .from(database.getClientList())
       .filter(activeInLastMonth())
       .transform(Functions.toStringFunction())
       .limit(10)
       .toList();

transform() هنا هو خريطة طريقة.فإنه يستخدم نفس الوظيفة<> "رد" كما Collections.transform().قائمة عدت للقراءة فقط على الرغم من استخدام copyInto() للحصول على قراءة-كتابة قائمة.

وإلا بالطبع عندما java8 يخرج مع lambdas هذا سوف يكون عفا عليها الزمن.

هذا lib وظيفي آخر يمكنك استخدامه خريطة: http://code.google.com/p/totallylazy/

sequence(1, 2).map(toString); // lazily returns "1", "2"

على الرغم من أنه سؤال قديم أود أن أظهر حلًا آخر:

فقط حدد عمليتك الخاصة باستخدام جافا جيرلايس وجافا 8 تدفقات:

public static <S, T> List<T> mapAll(Collection<S> collection, Function<S, T> mapper) {
   return collection.stream().map(mapper).collect(Collectors.toList());
}

مما يمكنك كتابة رمز مثل هذا:

List<String> hex = mapAll(Arrays.asList(10, 20, 30, 40, 50), Integer::toHexString);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top