Java 8 יוצא ב-18 במרץ 2014. זה זמן רב אבל עדיין פרוייקטים רבים פועלים על Java 8. זה קורה משום שהוא היה גרסה ראשית עם המון תכונות חדשות. בואו נסתכל על כל התכונות המרגשות והעיקריות של Java 8 עם קוד דוגמא.
סקירה מהירה של תכונות Java 8
כמה מהתכונות החשובות של Java 8 הן;
- forEach() שיטה בממשק Iterable
- שיטות ברירת מחדל וסטטיות בממשקים
- ממשקי פונקציונליות וביטויי Lambda
- API של Java Stream לפעולות מספר גדולות על מבני נתונים
- API של זמן ב-Java
- שיפורים ב-API של אוסף
- שיפורים ב-API של תכנות רציף
- שיפורים ב-IO של Java
בואו נסתכל בצורה קצרה על אלה תכונות של Java 8. אספק קטעי קוד עבור הבנת התכונות בצורה פשוטה.
1. forEach() שיטה בממשק Iterable
בכל פעם שאנו צריכים לעבור דרך אוסף, אנו צריכים ליצור Iterator שמטרתו היא לעבור במעגל, ואז יש לנו לוגיקת עסקים בלולאה עבור כל אחד מהאיברים באוסף. עשוי להתקבל ConcurrentModificationException אם האיטרטור לא משמש כראוי.
Java 8 הציגה את שיטת forEach בממשק java.lang.Iterable כך שבעת כתיבת הקוד אנו מתמקדים בלוגיקת עסקים. שיטת forEach מקבלת אובייקט java.util.function.Consumer כארגומנט, ולכן היא עוזרת לנו להפריד את הלוגיקה של העסקים במיקום נפרד שנוכל להשתמש בו מחדש. בואו נראה את שימוש ב- forEach עם דוגמה פשוטה.
מספר השורות עשוי להגדיל אך forEach עוזרת בהפרדת הלוגיקה לעבודת העסקים ולוגיקת העגלה במקום נפרד, תורמת לקוד נקי ולהפרדת תחומים נקיים יותר.
2. שיטות ברירת מחדל וסטטיות בממשקים
אם תקראו את פרטי השיטה forEach בזהירות, תגלו שהיא מוגדרת בממשק Iterable, אך אנו יודעים שממשקים לא יכולים לכלול גוף של שיטה. החידוש מ-Java 8 הוא שממשקים משופרים לכלול שיטה עם מימוש. אנו יכולים להשתמש במילת המפתח default ובמילת המפתח static כדי ליצור ממשקים עם מימוש של שיטה. מימוש השיטה forEach בממשק Iterable הוא:
אנו יודעים ש-Java לא מספקת ירושה מרובה במחלקות מכיוון שזה מביא לבעיה של יהלום. אז איך זה יטופל עם ממשקים עכשיו מאחר שהם דומים כעת למחלקות מופשטות?
הפתרון הוא שהמהדר יזרוק חריגה במקרה זה ונצטרך לספק לוגיקת מימוש במחלקה המממשת את הממשקים.
שים לב ששני הממשקים יש להם שיטה משותפת log() עם הלוגיקה של המימוש.
כפי שניתן לראות שמקום Interface1 יש מימוש של שיטת סטטית שמשמשת במימוש של MyClass.log()
. Java 8 משתמשת במידות default ו־static באופן רב ב-API Collection ושיטות ברירת המחדל מתווספות כדי שהקוד שלנו יישאר תואם לאחור.
אם כיתה כלשהי בהיררכיה מכילה שיטה עם אותה חתימה, אז שיטות ברירת המחדל הופכות ללא רלוונטיות. Object הוא המחלקה הבסיסית, כך שאם יש לנו שיטות ברירת מחדל כמו equals(), hashCode() בממשק, הן תהפוך ללא רלוונטיות. לכן למען בהירות טובה יותר, לא מותר לממש מתודות ברירת המחדל של Object בממשקים.
לפרטים מלאים על שינויי הממשק ב-Java 8, נא לקרוא את שינויי הממשק ב-Java 8.
3. ממשקים פונקציונליים וביטויי למבדר
אם אתה מבחין בקוד הממשק שמעל, תגלה את האישור @FunctionalInterface. ממשקי פונקציונליות הם מושג חדש שהוכנס ב-Java 8. ממשק עם בדיוק אחת מתודה מופשטת הופך להיות ממשק פונקציונלי. אנו לא צריכים להשתמש בתגית @FunctionalInterface כדי לסמן ממשק כממשק פונקציונלי.
@FunctionalInterface היא מתן למניעת הוספת מתודות מופשטות במקרים של ממשקים פונקציונליים. ניתן לחשוב על זה כמו על ההערה @Override וזה נחשב לפרקטיקה מומלצת להשתמש בו. ממשק ה- java.lang.Runnable עם מתודה מופשטת אחת בשם run() הוא דוגמה נהדרת לממשק פונקציונלי.
אחד היתרונות המרכזיים של הממשק הפונקציונלי הוא האפשרות להשתמש בביטויי lambda כדי ליצור אותם. אנו יכולים ליצור ממשק עם כיתה אנונימית אך הקוד נראה מפוחד.
מאחר ובממשקים פונקציונליים יש רק מתודה אחת, ביטויי lambda יכולים בקלות לספק את המימוש של המתודה. עלינו רק לספק ארגומנטים ולוגיקת עסקים. לדוגמה, אנו יכולים לכתוב את המימוש הנ"ל בעזרת ביטוי lambda כך:
אם יש לך אחת במימוש המתודה, אין צורך בסוגריים מסולסלים גם. לדוגמה, ממשק1 של המחלקה אנונימית יכול להיות מופעל בעזרת lambda כך:
אז לימבדה expressions הם דרך ליצירת מחלקות אנונימיות של ממשקי פונקציונל בקלות. אין יתרונות זמן ריצה בשימוש ב־lambda expressions, אז אני אשתמש בהם בזהירות מאחר ואין לי בעיה לכתוב כמה שורות קוד נוספות.
A new package java.util.function
has been added with bunch of functional interfaces to provide target types for lambda expressions and method references. Lambda expressions are a huge topic, I will write a separate article on that in the future.
ניתן לקרוא את המדריך המלא ב־Java 8 Lambda Expressions Tutorial.
4. ממשק Stream API של Java לפעולות מסוג המון על מובנים
A new java.util.stream
has been added in Java 8 to perform filter/map/reduce like operations with the collection. Stream API will allow sequential as well as parallel execution. This is one of the best features for me because I work a lot with Collections and usually with Big Data, we need to filter out them based on some conditions.
ממשק האוסף הוא מורחב עם שיטות ברירת מחדל של stream() ושל parallelStream() לקבלת הזרם לביצועים רצופים ופרלליים. בואו נצפה בשימושם עם דוגמה פשוטה.
אם תריצו את קטע הקוד הנ"ל, תקבלו פלט כמו זה:
שימו לב שערכי העיבוד הפרלליים אינם בסדר, לכן עיבוד פרללי יהיה מאוד מועיל בעבודה עם אוספים גדולים.
לכסות הכל על גבי Stream API אינו אפשרי בפוסט זה, תוכל לקרוא הכל על Stream API ב- Java 8 Stream API Example Tutorial.
5. Java Time API
תמיד היה קשה לעבוד עם תאריך, זמן ואזורי זמן ב-Java. לא היה לנו גישה או API סטנדרטי ב-Java לטיפול בתאריכים ובזמן. אחת התוספות הנחמדות ב-Java 8 היא החבילה java.time
שתקפיץ את תהליך העבודה עם זמן ב-Java.
כרקע ראשון ב-API החדש של זמן ב-Java, אני יכול להרגיש שזה יהיה מאוד קל לשימוש. יש כמה תת-חבילות: java.time.format שמספקת קלאסים להדפסה ולפירוק של תאריכים וזמנים, ו-java.time.zone שמספקת תמיכה באזורי זמן ובחוקיהם.
ה-API החדש לזמן מעדיף את האינומים על פני הקבועים השלמים לחודשים ולימים בשבוע. אחד הקלאסים השימושיים הוא DateTimeFormatter להמרת אובייקטי DateTime למחרוזות. למדריך מלא, תעבור ל- Java Date Time API Example Tutorial.
6. Collection API improvements
ישנן כבר את שיטת forEach() וממשק ה-Stream API לאוספים. כמה שיטות חדשות הוספו ל-API של Collection:
Iterator
שיטת ברירת מחדלforEachRemaining(Consumer action)
לביצוע הפעולה הנתונה עבור כל האיברים הנותרים עד שכל האיברים עוברים עיבוד או שהפעולה זורקת חריגה.Collection
שיטת ברירת מחדלremoveIf(Predicate filter)
להסרת כל האיברים באוסף זה שמקיימים את התנאי הנתון.Collection
שיטתspliterator()
המחזירה מופע של Spliterator שניתן להשתמש בו כדי לעבור על האיברים בצורה רציפה או מקבוצה.- Map
replaceAll()
,compute()
,merge()
שיטות. - שיפור בביצועים עבור מחלקת HashMap עם התנגשויות בין מפות מפתחות.
7. שיפורי API תחרותיות
כמה שיפורי API תחרותיים חשובים הם:
ConcurrentHashMap
שיטות compute(), forEach(), forEachEntry(), forEachKey(), forEachValue(), merge(), reduce() ו- search().CompletableFuture
שיכול להושלם באופן פורמלי (בהגדרת ערך ומצב שלו).Executors
שיטתnewWorkStealingPool()
ליצירת בריכת תהליכים מסוג WorkStealing שמשתמשת בכל התהליכים הזמינים כרמת פרלליזם שלו.
8. שיפורים ב- Java IO
כמה מהשיפורים ב-IO שידועים לי הם:
Files.list(Path dir)
שמחזיר זרם שנמלא באופן עצלני, שבו האיברים הם הרשומות בתיקייה.Files.lines(Path path)
שקורא את כל השורות מקובץ כזרם.Files.find()
שמחזיר זרם שנמלא באופן עצלני עם נתיבים על ידי חיפוש אחר קבצים בעץ קבצים שמשתמש בקובץ התחלה נתון.BufferedReader.lines()
שמחזיר זרם שהאיברים בו הם שורות שנקראו מ- BufferedReader זה.
שיפורי ממשק ה- Core API של Java 8 השונים
כמה שיפורים שונים ב-API שעשויים להיות שימושיים הם:
- פעולה סטטית של ThreadLocal באמצעות השיטה withInitial(Supplier supplier) ליצירת מופעים בקלות.
- הממשק Comparator הוארך עם הרבה שיטות ברירת מחדל וסטטיות לסדר טבעי, סדר הפוך, וכו '.
- שיטות min(), max() ו- sum() במחלקות העטיפה Integer, Long ו- Double.
- השיטות logicalAnd(), logicalOr() ו- logicalXor() במחלקת Boolean.
- שיטת stream() במחלקת ZipFile כדי לקבל Stream מסודר על פריטי קובץ ה-ZIP. הפריטים מופיעים ב-Stream בסדר שבו הם מופיעים בפנימיה של קובץ ה-ZIP.
- כמה שיטות עזר במחלקת Math.
- נוסף פקודת jjs להפעלת מנוע Nashorn.
- נוסף פקודת jdeps לניתוח של קבצי המחלקות
- נסרק JDBC-ODBC Bridge.
- הוסרה זיכרון המרחב PermGen
זהו כל התכונות של Java 8 עם דוגמאות. אם פספסתי תכונות חשובות של Java 8, אנא הודיעו לי דרך תגובות.
Source:
https://www.digitalocean.com/community/tutorials/java-8-features-with-examples