![حلقه نوشتن را متوقف کنید! 10 روش برتر برای کار با مجموعه ها در جاوا 8 - 1]()
همانطور که می دانید عادت های ما طبیعت دوم هستند. و هنگامی که به نوشتن عادت کردید
for (int i = 0; i <......)
، هیچ بخشی از شما نمیخواهد این ساختار را دوباره یاد بگیرد (مخصوصاً که بسیار ساده و قابل درک است). با این حال، حلقه ها اغلب به طور مکرر برای انجام همان عملیات اصلی استفاده می شوند، و تکرار چیزی است که ما بسیار دوست داریم از آن خلاص شویم. با جاوا 8، اوراکل تصمیم گرفته است به ما در انجام این کار کمک کند. در زیر 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 (فیلتر Predicate<? 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> action)
این
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، BiFunction<? super K، ? super V، ? extensions 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));
اولین فراخوانی تابع هیچ تغییری نکرد، زیرا کتابی با عنوان "یوجین اونگین" در ما وجود ندارد
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 مقدار پیش فرض)
این متد مقدار مربوط به را برمی گرداند
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
for this است 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)
همین کار را انجام می دهد، اما فقط در صورتی که مقدار فعلی for 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
بدون هیچ ساختار پیچیده تغییر دادیم! PS عادت کردن به جدید همیشه دشوار است، اما این تغییرات واقعا خوب هستند. در هر صورت، برخی از قسمت های کد من قطعا کمتر از قبل شبیه اسپاگتی است :) موفق باشید در یادگیری!
GO TO FULL VERSION