כפי שאתה יודע, ההרגלים שלנו הם טבע שני. וברגע שאתה מתרגל לכתוב for (int i = 0; i <......), אף חלק ממך לא רוצה ללמוד מחדש את המבנה הזה (במיוחד שהוא די פשוט ומובן). עם זאת, לולאות משמשות פעמים רבות לביצוע אותן פעולות בסיסיות, וחזרה היא משהו שהיינו מאוד רוצים להיפטר ממנו. עם Java 8, אורקל החליטה לעזור לנו לעשות זאת. להלן 10 שיטות האיסוף הטובות ביותר שיחסכו לך המון זמן וקוד.
1. Iterable.forEach(פעולה Consumer <? Super T>)
השם מדבר בעד עצמו. הוא חוזר על האוסף שהועבר כארגומנט, ומבצע את ביטוי הפעולה למבדה עבור כל אחד מהמרכיבים שלו.
בשורה אחת, אנו מסירים מהרשימה את כל המספרים הגדולים מ-5.
3. Map.forEach(פעולה BiConsumer <? super K, ? super V>)
השיטה forEachפועלת לא רק עבור מחלקות שמיישמות את Collectionהממשק, אלא גם עבור Map.
Map<String,String> books =newHashMap<>();
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:TheBrothersKaramazov. Author:FyodorDostoevskyBook title:Thinking in Java. Author:BruceEckelBook title:Crime and Punishment. Author:FyodorDostoevskyBook title:War and Peace. Author:LeoTolstoyBook title:Lord of the Rings. Author:JohnTolkien
4. Map.compute (מקש K, BiFunction<? Super K,? Super V,? Extends V> remappingFunction)
נראה קצת יותר מאיים, אבל למעשה פשוט, כמו כל הקודמים. שיטה זו קובעת keyאת הערך של התוצאה של הביצוע mappingFunction. לדוגמה:
Map<String,String> books =newHashMap<>();
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:TheBrothersKaramazov. Author:FyodorDostoevskyBook title:Thinking in Java. Author:BruceEckelBook title:Crime and Punishment. Author:FyodorDostoevskyBook title:War and Peace. Author:LeoTolstoyBook title:Lord of the Rings. Author:JohnTolkien
_______________________
Book title:TheBrothersKaramazov. Author:FyodorDostoevskyBook title:Thinking in Java. Author:BruceEckel, cool dude
Book title:Crime and Punishment. Author:FyodorDostoevskyBook title:War and Peace. Author:LeoTolstoyBook title:Lord of the Rings. Author:JohnTolkien
המחבר של "לחשוב בג'אווה" בהחלט מגניב! :)
5. Map.computeIfAbsent(מקש K, פונקציה <? super K, ? מרחיב את V> mappingFunction)
שיטה זו תוסיף אלמנט חדש ל- Map, אבל רק אם אין לה כבר אלמנט עם המפתח הזה. הערך שהוקצה יהיה תוצאה של ביצוע ה- mappingFunction. אם רכיב עם המפתח כבר קיים, הוא לא ידרוס. זה פשוט יישאר כמו שהוא. בואו נחזור לספרים שלנו וננסה שיטה חדשה:
Map<String,String> books =newHashMap<>();
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));
Book title:TheBrothersKaramazov. Author:FyodorDostoevskyBook title:Thinking in Java. Author:BruceEckelBook title:Crime and Punishment. Author:FyodorDostoevskyBook title:War and Peace. Author:LeoTolstoyBook title:HarryPotter and the Prisoner of Azkaban. Author:JoanneRowlingBook title:Lord of the Rings. Author:JohnTolkien
6. Map.computeIfPresent(מפתח K, BiFunction<? super K, ? super V, ? מרחיב את V> remappingFunction)
כאן יש לנו את אותו עיקרון כמו Map.compute(), אבל החישובים מבוצעים רק אם פריט עם keyכבר קיים.
Map<String,String> books =newHashMap<>();
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:TheBrothersKaramazov. Author:FyodorDostoevskyBook title:Thinking in Java. Author:BruceEckelBook title:Crime and Punishment. Author:FyodorDostoevskyBook title:War and Peace. Author:LeoTolstoyBook title:Lord of the Rings. Author:JohnTolkien
_________________
Book title:TheBrothersKaramazov. Author:AlexanderPushkinBook title:Thinking in Java. Author:BruceEckelBook title:Crime and Punishment. Author:FyodorDostoevskyBook title:War and Peace. Author:LeoTolstoyBook title:Lord of the Rings. Author:JohnTolkien
7. Map.getOrDefault(מפתח אובייקט, V defaultValue)
שיטה זו מחזירה את הערך המתאים ל key. אם המפתח אינו קיים, הוא מחזיר את ערך ברירת המחדל.
Map<String,String> books =newHashMap<>();
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 =newHashMap<>();
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:TheBrothersKaramazov. Author:FyodorDostoevskyTitle:Thinking in Java. Author:BruceEckel and some coauthor
Title:Crime and Punishment. Author:FyodorDostoevskyTitle:War and Peace. Author:LeoTolstoyTitle:Lord of the Rings. Author:JohnTolkien
*סליחה, ברוס*
9. Map.putIfAbsent(מפתח K, ערך V)
בעבר, כדי להוסיף זוג ל- Map, אם הוא עדיין לא היה שם, היית צריך לעשות את הפעולות הבאות:
Map<String,String> map =newHashMap<>();if(map.get("Lord of the Rings")==null)
map.put("Lord of the Rings","John Tolkien");
עכשיו הכל הפך להרבה יותר קל:
Map<String,String> map =newHashMap<>();
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 =newHashMap<>();
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:TheBrothersKaramazov. Author:FyodorDostoevskyTitle:Thinking in Java. Author:BruceEckelTitle:Crime and Punishment. Author:FyodorDostoevskyTitle:War and Peace. Author:LeoTolstoyTitle:Lord of the Rings. Author:JohnTolkien
זה לא עבד! הערך הנוכחי למפתח "האחים קרמזוב" הוא "פיודור דוסטויבסקי", לא "ברוס אקל", כך ששום דבר לא השתנה.
Map books =newHashMap<>();
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));publicstaticStringgetCoolAuthor(){return"Cool author";}
Title:TheBrothersKaramazov. 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