كما تعلمون، عاداتنا هي طبيعة ثانية. وبمجرد أن تعتاد على الكتابة
for (int i = 0; i <......)
، لن يرغب أي جزء منك في إعادة تعلم هذه البنية (خصوصًا أنها بسيطة ومفهومة تمامًا). ومع ذلك، غالبًا ما يتم استخدام الحلقات بشكل متكرر لإجراء نفس العمليات الأساسية، والتكرار هو شيء نود التخلص منه بشدة. مع Java 8، قررت Oracle مساعدتنا في القيام بذلك. فيما يلي أفضل 10 طرق للتجميع ستوفر لك الكثير من الوقت والأكواد.
1. Iterable.forEach (إجراء المستهلك <؟ Super T>)
الاسم يتحدث عن نفسه. إنه يتكرر على المجموعة التي تم تمريرها كوسيطة، وينفذ تعبير لامدا الإجراء لكل عنصر من عناصره.List <Integer> numbers = new ArrayList<>(Arrays.asList(1,2,3,4,5,6,7));
numbers.forEach(s -> System.out.print(s + " "));
1 2 3 4 5 6 7
2. Collection.removeIf (مرشح المسند<؟ super E>)
مرة أخرى، لا يوجد شيء صعب هنا. تتكرر الطريقة عبر المجموعة وتزيل أي عناصر تطابقfilter
.
List <Integer> numbers = new ArrayList<>(Arrays.asList(1,2,3,4,5,6,7));
numbers.removeIf(s -> s > 5);
numbers.forEach(s -> System.out.print(s + " "));
في سطر واحد، نقوم بإزالة جميع الأرقام الأكبر من 5 من القائمة.
3. Map.forEach(إجراء BiConsumer <? super K, ? super V>)
لا تعمل هذهforEach
الطريقة فقط مع الفئات التي تنفذ الواجهة Collection
، ولكن أيضًا مع Map
.
Map <String, String> books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
books.forEach((a,b) -> System.out.println("Book title: " + a + ". Author: "+ b));
Book title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Book title: Thinking in Java. Author: Bruce Eckel
Book title: Crime and Punishment. Author: Fyodor Dostoevsky
Book title: War and Peace. Author: Leo Tolstoy
Book title: Lord of the Rings. Author: John Tolkien
4. Map.compute (مفتاح K، BiFunction<؟ Super K،؟ Super V،؟ Extends V> remappingFunction)
يبدو الأمر أكثر تخويفًا بعض الشيء، ولكنه في الحقيقة بسيط، مثل كل ما سبق. تقوم هذه الطريقة بتعيينkey
قيمة مساوية لنتيجة التنفيذ mappingFunction
. على سبيل المثال:
Map <String, String> books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
books.forEach((a,b) -> System.out.println("Book title: " + a + ". Author: "+ b));
books.compute("Thinking in Java", (a,b) -> b + ", cool dude");
System.out.println("_______________________");
books.forEach((a,b) -> System.out.println("Book title: " + a + ". Author: "+ b));
Book title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Book title: Thinking in Java. Author: Bruce Eckel
Book title: Crime and Punishment. Author: Fyodor Dostoevsky
Book title: War and Peace. Author: Leo Tolstoy
Book title: Lord of the Rings. Author: John Tolkien
_______________________
Book title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Book title: Thinking in Java. Author: Bruce Eckel, cool dude
Book title: Crime and Punishment. Author: Fyodor Dostoevsky
Book title: War and Peace. Author: Leo Tolstoy
Book title: Lord of the Rings. Author: John Tolkien
مؤلف كتاب "التفكير في جافا" رائع بالتأكيد! :)
5. Map.computeIfAbsent(مفتاح K، الوظيفة <؟ super K،؟ تمتد V> mappingFunction)
ستضيف هذه الطريقة عنصرًا جديدًا إلى الملفMap
، ولكن فقط إذا لم يكن يحتوي بالفعل على عنصر بهذا المفتاح. القيمة المخصصة ستكون نتيجة تنفيذ mappingFunction
. إذا كان العنصر الذي يحتوي على المفتاح موجودًا بالفعل، فلن تتم الكتابة فوقه. وسوف تبقى ببساطة كما هي. فلنعد إلى كتبنا ونجرب طريقة جديدة:
Map <String, String> books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
books.computeIfAbsent("Harry Potter and the Prisoner of Azkaban", b -> getHarryPotterAuthor());
books.forEach((a,b) -> System.out.println("Book title: " + a + ". Author: "+ b));
وهنا لدينا mappingFunction
:
public static String getHarryPotterAuthor() {
return "Joanne Rowling";
}
وها هو الكتاب الجديد:
Book title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Book title: Thinking in Java. Author: Bruce Eckel
Book title: Crime and Punishment. Author: Fyodor Dostoevsky
Book title: War and Peace. Author: Leo Tolstoy
Book title: Harry Potter and the Prisoner of Azkaban. Author: Joanne Rowling
Book title: Lord of the Rings. Author: John Tolkien
6. Map.computeIfPresent(K key, BiFunction<? super K, ? super V, ? Extends V> remappingFunction)
هنا لدينا نفس المبدأMap.compute()
، ولكن يتم إجراء الحسابات فقط إذا كان العنصر key
موجودًا بالفعل.
Map <String, String> books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
books.computeIfPresent("Eugene Onegin", (a,b) -> b = "Alexander Pushkin");
System.out.println("_________________");
books.forEach((a,b) -> System.out.println("Book title: " + a + ". Author: "+ b));
books.computeIfPresent("The Brothers Karamazov", (a,b) -> b = "Alexander Pushkin");
System.out.println("_________________");
books.forEach((a,b) -> System.out.println("Book title: " + a + ". Author: "+ b));
لم يتم إجراء أي تغييرات على الاستدعاء الأول للوظيفة، لأنه لا يوجد كتاب بعنوان "Eugene Onegin" في ملف Map
. لكن في المكالمة الثانية، غيّر البرنامج مؤلف كتاب "الإخوة كارامازوف" إلى ألكسندر بوشكين. انتاج:
_________________
Book title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Book title: Thinking in Java. Author: Bruce Eckel
Book title: Crime and Punishment. Author: Fyodor Dostoevsky
Book title: War and Peace. Author: Leo Tolstoy
Book title: Lord of the Rings. Author: John Tolkien
_________________
Book title: The Brothers Karamazov. Author: Alexander Pushkin
Book title: Thinking in Java. Author: Bruce Eckel
Book title: Crime and Punishment. Author: Fyodor Dostoevsky
Book title: War and Peace. Author: Leo Tolstoy
Book title: Lord of the Rings. Author: John Tolkien
7. Map.getOrDefault(مفتاح الكائن، V defaultValue)
تقوم هذه الطريقة بإرجاع القيمة المقابلة لـkey
. إذا كان المفتاح غير موجود، فإنه يقوم بإرجاع القيمة الافتراضية.
Map <String, String> books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
String igor = books.getOrDefault("The Tale of Igor's Campaign", "Unknown author");
System.out.println(igor);
هذا مريح للغاية:
Unknown author
8. Map.merge (مفتاح K، قيمة V، BiFunction<? super V, ? super V, ? يمتد V> remappingFunction)
لم أكلف نفسي حتى عناء محاولة حساب عدد أسطر التعليمات البرمجية التي ستوفر لك هذه الطريقة.- إذا
key
لم يكن موجودًا في ملفكMap
، أو إذاvalue
كان هذا المفتاح موجودًاnull
، فستضيف الطريقةkey-value
الزوج الذي تم تمريره إلى ملفMap
. - إذا
key
كان موجودًاvalue != null
، فإن الطريقة تغير قيمتها إلى نتيجة التنفيذremappingFunction
. - إذا
remappingFunction
تم إرجاعهnull
، فسيتمkey
إزالته من المجموعة.
Map <String, String> books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
books.merge("Thinking in Java", "Bruce Eckel", (a, b) -> b + " and some coauthor");
books.forEach((a, b) -> System.out.println("Title: " + a + ". Author: "+ b));
انتاج:
Title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Title: Thinking in Java. Author: Bruce Eckel and some coauthor
Title: Crime and Punishment. Author: Fyodor Dostoevsky
Title: War and Peace. Author: Leo Tolstoy
Title: Lord of the Rings. Author: John Tolkien
*آسف يا بروس*
9. Map.putIfAbsent(مفتاح K، قيمة V)
في السابق، لإضافة زوج إلى ملفMap
، إذا لم يكن موجودًا بالفعل، كان عليك القيام بما يلي:
Map <String, String> map = new HashMap<>();
if (map.get("Lord of the Rings") == null)
map.put("Lord of the Rings", "John Tolkien");
الآن أصبح كل شيء أسهل بكثير:
Map<String, String> map = new HashMap<>();
map.putIfAbsent("Lord of the Rings", "John Tolkien");
10. Map.replace وMap.replaceAll()
أخيراً وليس آخراً.Map.replace(K key, V newValue)
يستبدلkey
قيمة ' بـnewValue
، إذا كان هذا المفتاح موجودًا. إذا لم يكن الأمر كذلك، فلن يحدث شيء.Map.replace(K key, V oldValue, V newValue)
يفعل نفس الشيء، ولكن فقط إذا كانت القيمة الحاليةkey
لـ تساويoldValue
.Map.replaceAll(BiFunction<? super K, ? super V, ? extends V> function)
يستبدل كلvalue
بنتيجة الوظيفة.
Map <String, String> books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
books.replace("The Brothers Karamazov", "Bruce Eckel", "John Tolkien");
books.forEach((a, b) -> System.out.println("Title: " + a + ". Author: "+ b));
Title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Title: Thinking in Java. Author: Bruce Eckel
Title: Crime and Punishment. Author: Fyodor Dostoevsky
Title: War and Peace. Author: Leo Tolstoy
Title: Lord of the Rings. Author: John Tolkien
لم ينجح الأمر! القيمة الحالية لمفتاح "الأخوة كارامازوف" هي "فيودور دوستويفسكي"، وليس "بروس إيكل"، لذلك لم يتغير شيء.
Map books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
books.replaceAll((a,b) -> getCoolAuthor());
books.forEach((a, b) -> System.out.println("Title: " + a + ". Author: "+ b));
public static String getCoolAuthor() {
return "Cool author";
}
Title: The Brothers Karamazov. Author: Cool author
Title: Thinking in Java. Author: Cool author
Title: Crime and Punishment. Author: Cool author
Title: War and Peace. Author: Cool author
Title: Lord of the Rings. Author: Cool author
لقد قمنا بسهولة بتغيير القيم للكل Map
دون أي بنيات معقدة! ملحوظة: التعود على الجديد أمر صعب دائمًا، لكن هذه التغييرات جيدة حقًا. على أية حال، بعض أجزاء الكود الخاص بي أصبحت بالتأكيد أقل شبهاً بالسباجيتي من ذي قبل :) حظًا سعيدًا في التعلم!
GO TO FULL VERSION