CodeGym /בלוג Java /Random-HE /תפסיק לכתוב לופים! 10 שיטות עבודה מומלצות לעבודה עם אוספי...
John Squirrels
רָמָה
San Francisco

תפסיק לכתוב לופים! 10 שיטות עבודה מומלצות לעבודה עם אוספים ב-Java 8

פורסם בקבוצה
תפסיק לכתוב לופים!  10 שיטות עבודה מומלצות לעבודה עם אוספים ב-Java 8 - 1 כפי שאתה יודע, ההרגלים שלנו הם טבע שני. וברגע שאתה מתרגל לכתוב for (int i = 0; i <......), אף חלק ממך לא רוצה ללמוד מחדש את המבנה הזה (במיוחד שהוא די פשוט ומובן). עם זאת, לולאות משמשות פעמים רבות לביצוע אותן פעולות בסיסיות, וחזרה היא משהו שהיינו מאוד רוצים להיפטר ממנו. עם Java 8, אורקל החליטה לעזור לנו לעשות זאת. להלן 10 שיטות האיסוף הטובות ביותר שיחסכו לך המון זמן וקוד.

1. Iterable.forEach(פעולה Consumer <? 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>)

השיטה 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, ? מרחיב את 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 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)

אפילו לא טרחתי לנסות לחשב כמה שורות קוד שיטה זו תחסוך לך.
  1. אם keyלא קיים ב- שלך Map, או אם valueהמפתח הזה הוא null, אז השיטה מוסיפה את key-valueהזוג שעבר ל- Map.
  2. אם keyאכן קיימת value != null, אז השיטה משנה את ערכה לתוצאה של ביצוע remappingFunction.
  3. אם 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()

אחרון חביב.
  1. Map.replace(K key, V newValue)מחליף keyאת הערך של newValue, אם מפתח כזה קיים. אם לא, שום דבר לא קורה.
  2. Map.replace(K key, V oldValue, V newValue)עושה את אותו הדבר, אבל רק אם הערך הנוכחי עבור keyשווה ל oldValue.
  3. 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ללא בנייה מסובכת! נ.ב. תמיד קשה להתרגל לחדש, אבל השינויים האלה ממש טובים. בכל מקרה, חלקים מסוימים בקוד שלי בהחלט פחות דומים לספגטי מבעבר :) בהצלחה בלמידה!
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION