אוספי Apache Commons לעומת גוגל גויאבה

1. סקירה כללית

במדריך זה נשווה שתי ספריות קוד פתוח מבוססות Java: Apache Commons ו- Google Guava. בשתי הספריות מערך תכונות עשיר עם הרבה ממשקי API של שירות בעיקר באוספים ובקלט / פלט.

בקיצור, כאן נתאר רק קומץ מהמשתמשים הנפוצים ביותר במסגרת האוספים יחד עם דוגמאות קוד. נראה גם סיכום ההבדלים ביניהם.

בנוסף, יש לנו אוסף של מאמרים לצלילה עמוקה לנחלות שונות ולכלי עזר של גויאבה.

2. היסטוריה קצרה של שתי הספריות

גוגל גויאבה הוא פרויקט של גוגל, שפותח בעיקר על ידי מהנדסי הארגון, אם כי הוא נפתח כעת. ה המניע העיקרי להתחיל היה לכלול גנריות שהוכנסו ב- JDK 1.5 למסגרת Java Collections, או JCF, ולשפר את יכולתו.

מאז הקמתה הרחיבה הספרייה את יכולותיה וכוללת כעת גרפים, תכנות פונקציונלי, אובייקטים לטווח, אחסון במטמון ו- חוּט מָנִיפּוּלָצִיָה.

Apache Commons התחיל כפרויקט בג'קרטה להשלמת ממשק ה- API של אוספי Java, ובסופו של דבר הפך לפרויקט של קרן Apache Software. עם השנים הוא התרחב לרפרטואר עצום של רכיבי ג'אווה לשימוש חוזר בתחומים שונים אחרים, כולל (אך לא מוגבל) הדמיה, קלט / פלט, הצפנה, אחסון במטמון, נטוורקינג, אימות ואיחוד עצמים.

מכיוון שמדובר בפרויקט קוד פתוח, מפתחים מקהילת אפאצ'י ממשיכים להוסיף לספרייה זו כדי להרחיב את יכולותיה. למרות זאת, הם מקפידים מאוד לשמור על תאימות לאחור.

3. תלות של Maven

כדי לכלול את גויאבה, עלינו להוסיף את התלות שלה לזה שלנו pom.xml:

 com.google.guava גויאבה 29.0-jre 

ניתן למצוא את המידע על הגרסה העדכנית ביותר ב- Maven.

עבור Apache Commons זה קצת שונה. תלוי בתוכנת השירות בה אנו רוצים להשתמש, עלינו להוסיף את זה המסוים. לדוגמה, עבור אוספים עלינו להוסיף:

 org.apache.commons commons-collection4 4.4 

בדוגמאות הקוד שלנו נשתמש 4.

בוא נקפוץ לחלק המהנה עכשיו!

4. מפות דו כיווניות

מפות אליהן ניתן לגשת באמצעות המקשים שלהן, כמו גם ערכים, מכונות מפות דו-כיווניות. ל- JCF אין תכונה זו.

בואו נראה איך שתי הטכנולוגיות שלנו מציעות אותן. בשני המקרים ניקח דוגמא לימי השבוע כדי לקבל את שם היום בהתחשב במספרו ולהיפך.

4.1. של גויאבה BiMap

גויאבה מציעה ממשק - BiMap, כמפה דו-כיוונית. זה יכול להיות מיידי עם אחד היישומים שלה EnumBiMap, EnumHashBiMap, HashBiMap, או ImmutableBiMap.

כאן אנו משתמשים HashBiMap:

BiMap daysOfWeek = HashBiMap.create ();

אכלוס זה דומה לכל מפה ב- Java:

daysOfWeek.put (1, "יום שני"); daysOfWeek.put (2, "יום שלישי"); daysOfWeek.put (3, "יום רביעי"); daysOfWeek.put (4, "יום חמישי"); daysOfWeek.put (5, "יום שישי"); daysOfWeek.put (6, "שבת"); daysOfWeek.put (7, "יום ראשון");

והנה כמה מבחני JUnit להוכחת הרעיון:

@Test הציבור בטל givenBiMap_whenValue_thenKeyReturned () {assertEquals (Integer.valueOf (7), daysOfWeek.inverse (). Get ("יום ראשון")); } @Test הציבור בטל givenBiMap_whenKey_thenValueReturned () {assertEquals ("יום שלישי", daysOfWeek.get (2)); }

4.2. של אפאצ'י BidiMap

באופן דומה, אפאצ'י מספק לנו את זה BidiMap מִמְשָׁק:

BidiMap daysOfWeek = TreeBidiMap חדש ();

כאן אנו משתמשים TreeBidiMap. עם זאת, ישנם יישומים אחרים, כגון DualHashBidiMap ו DualTreeBidiMap גם כן.

כדי לאכלס אותו, אנו יכולים לשים את הערכים כפי שעשינו BiMap מֵעַל.

השימוש בו די דומה גם:

@Test public void givenBidiMap_whenValue_thenKeyReturned () {assertEquals (Integer.valueOf (7), daysOfWeek.inverseBidiMap (). Get ("יום ראשון")); } @Test הציבור בטל givenBidiMap_whenKey_thenValueReturned () {assertEquals ("יום שלישי", daysOfWeek.get (2)); }

בכמה מבחני ביצוע פשוטים, מפה דו-כיוונית זו פיגר אחרי מקבילו בגויאבה רק בהכנסות. זה היה הרבה יותר מהיר באחירת מפתחות כמו גם בערכים.

5. מפת מקשים לערכים מרובים

למקרה שימוש בו נרצה למפות מספר מפתחות לערכים שונים, כמו אוסף עגלות מכולת לפירות וירקות, שתי הספריות מציעות לנו פתרונות ייחודיים.

5.1. של גויאבה MultiMap

ראשית, בואו נראה כיצד לאתחל ולאתחל MultiMap:

Multimap groceryCart = ArrayListMultimap.create (); groceryCart.put ("פירות", "תפוח עץ"); groceryCart.put ("פירות", "ענבים"); groceryCart.put ("פירות", "תותים"); groceryCart.put ("ירקות", "תרד"); groceryCart.put ("ירקות", "כרוב");

לאחר מכן נשתמש בכמה מבחני JUnit כדי לראות את זה בפעולה:

@ מבחן חלל ציבורי givenMultiValuedMap_whenFruitsFetched_thenFruitsReturned () {רשימה פירות = Arrays.asList ("תפוח", "ענבים", "תותים"); assertEquals (פירות, groceryCart.get ("פירות")); } @Test הציבור בטל givenMultiValuedMap_whenVeggiesFetched_thenVeggiesReturned () {רשימה ירקות = Arrays.asList ("תרד", "כרוב"); assertEquals (ירקות, groceryCart.get ("ירקות")); } 

בנוסף, MultiMap נותן לנו את היכולת להסיר ערך נתון או מערך שלם של ערכים מהמפה:

@Test הציבור בטל givenMultiValuedMap_whenFuitsRemoved_thenVeggiesPreserved () {assertEquals (5, groceryCart.size ()); groceryCart.remove ("פירות", "תפוח עץ"); assertEquals (4, groceryCart.size ()); groceryCart.removeAll ("פירות"); assertEquals (2, groceryCart.size ()); }

כפי שאנו רואים, כאן הסרנו לראשונה תפוח עץ מ ה פירות להגדיר ואז להסיר את כל זה פירות מַעֲרֶכֶת.

5.2. של אפאצ'י MultiValuedMap

שוב, בואו נתחיל בהפעלת א MultiValuedMap:

MultiValuedMap groceryCart = חדש ArrayListValuedHashMap ();

מכיוון שאכלוס זה זהה לזה שראינו בסעיף הקודם, בואו נסתכל במהירות על השימוש:

@ מבחן חלל ציבורי givenMultiValuedMap_whenFruitsFetched_thenFruitsReturned () {רשימה פירות = Arrays.asList ("תפוח", "ענבים", "תותים"); assertEquals (פירות, groceryCart.get ("פירות")); } @Test הציבור בטל givenMultiValuedMap_whenVeggiesFetched_thenVeggiesReturned () {רשימה ירקות = Arrays.asList ("תרד", "כרוב"); assertEquals (ירקות, groceryCart.get ("ירקות")); }

כפי שאנו רואים, השימוש בו הוא גם זהה!

עם זאת, במקרה זה, אין לנו את הגמישות להסיר ערך אחד, כגון תפוח עץ מ פירות.אנחנו יכולים להסיר רק את כל ערכת ה- פירות:

@Test הציבור בטל givenMultiValuedMap_whenFuitsRemoved_thenVeggiesPreserved () {assertEquals (5, groceryCart.size ()); groceryCart.remove ("פירות"); assertEquals (2, groceryCart.size ()); }

6. מיפוי מקשים מרובים לערך אחד

כאן, ניקח דוגמה לקווי רוחב ואורך שיש למפות לערים בהתאמה:

cityCoordinates.put ("40.7128 ° N", "74.0060 ° W", "ניו יורק"); cityCoordinates.put ("48.8566 ° N", "2.3522 ° E", "Paris"); cityCoordinates.put ("19.0760 ° N", "72.8777 ° E", "מומבאי");

כעת נראה כיצד להשיג זאת.

6.1. של גויאבה שולחן

גויאבה מציעה את שלה שולחן העומד בתנאי השימוש לעיל:

טבלה cityCoordinates = HashBasedTable.create ();

והנה כמה שימושים שאנו יכולים להפיק ממנו:

@ מבחן הריק ציבורי givenCoordinatesTable_whenFetched_thenOK () {List expectLongitudes = Arrays.asList ("74.0060 ° W", "2.3522 ° E", "72.8777 ° E"); assertArrayEquals (expectLongitudes.toArray (), cityCoordinates.columnKeySet (). toArray ()); רשימת expectCities = Arrays.asList ("ניו יורק", "פריז", "מומבאי"); assertArrayEquals (expectCities.toArray (), cityCoordinates.values ​​(). toArray ()); assertTrue (cityCoordinates.rowKeySet (). מכיל ("48.8566 ° N")); }

כפי שאנו רואים, אנו יכולים להשיג מַעֲרֶכֶת תצוגה של השורות, העמודות והערכים.

שולחן מציע לנו גם אפשרות לשאול את השורות או העמודות שלו.

בואו ניקח בחשבון שולחן סרטים כדי להדגים זאת:

סרטי שולחן = HashBasedTable.create (); movies.put ("טום הנקס", "מג ראיין", "יש לך דואר"); movies.put ("טום הנקס", "קתרין זיטה ג'ונס", "הטרמינל"); movies.put ("בראדלי קופר", "ליידי גאגא", "כוכב נולד"); movies.put ("Keenu Reaves", "Sandra Bullock", "Speed"); movies.put ("טום הנקס", "סנדרה בולוק", "חזק במיוחד וקרוב להפליא");

והנה כמה חיפושים מדויקים, שמסבירים את עצמנו, שאנחנו יכולים לעשות על שלנו סרטיםשולחן:

@Test הציבור בטל givenMoviesTable_whenFetched_thenOK () {assertEquals (3, films.row ("טום הנקס"). גודל ()); assertEquals (2, films.column ("סנדרה בולוק"). גודל ()); assertEquals ("כוכב נולד", films.get ("בראדלי קופר", "ליידי גאגא")); assertTrue (films.containsValue ("מהירות")); }

למרות זאת, שולחן מגביל אותנו למפות רק שני מקשים לערך. עדיין אין לנו אלטרנטיבה בגויאבה למפות יותר משני מקשים לערך יחיד.

6.2. של אפאצ'י MultiKeyMap

חוזרים אל שלנו עיר קואורדינטות לדוגמה, כך נוכל לתפעל את זה באמצעות MultiKeyMap:

@Test ציבורי בטל שניתןCoordinatesMultiKeyMap_whenQueried_thenOK () {MultiKeyMap cityCoordinates = MultiKeyMap חדש (); // אכלס עם מקשים וערכים כפי שמוצג קודם. צפה ב- LongLengthitudes = Arrays.asList ("72.8777 ° E", "2.3522 ° E", "74.0060 ° W"); רשימת קווי אורך = ArrayList חדש (); cityCoordinates.forEach ((מפתח, ערך) -> {longitudes.add (key.getKey (1));}); assertArrayEquals (expectLongitudes.toArray (), longitudes.toArray ()); רשימת expectCities = Arrays.asList ("מומבאי", "פריז", "ניו יורק"); רשימת ערים = ArrayList חדש (); cityCoordinates.forEach ((key, value) -> {cities.add (value);}); assertArrayEquals (expectCities.toArray (), ערים. toArray ()); }

כפי שניתן לראות מקטע הקוד לעיל, להגיע לאותן טענות כמו לגבי גויאבה שולחן, היינו צריכים לחזור על ה MultiKeyMap.

למרות זאת, MultiKeyMap מציע גם אפשרות למפות יותר משני מקשים לערך. לדוגמא, זה נותן לנו את היכולת למפות את ימי השבוע כימי חול או סופי שבוע:

@Test הציבור בטל givenDaysMultiKeyMap_whenFetched_thenOK () {ימים = MultiKeyMap חדש (); days.put ("יום שני", "יום שלישי", "יום רביעי", "יום חמישי", "יום שישי", "יום חול"); days.put ("שבת", "יום ראשון", "סוף שבוע"); assertFalse (days.get ("שבת", "יום ראשון"). שווה ("יום חול")); }

7. אוספי Apache Commons לעומת גוגל גויאבה

לפי המהנדסים שלה, גוגל גויאבה נולד מהצורך להשתמש בגנריות בספרייה, ש- Apache Commons לא הציעה. זה גם עוקב אחר דרישות ה- API של אוספים לתחת. יתרון מרכזי נוסף הוא בכך שהוא נמצא בפיתוח פעיל עם מהדורות חדשות שיוצאות לעתים קרובות.

עם זאת, אפאצ'י מציע יתרון בכל מה שקשור לביצועים בזמן שמביא ערך מאוסף. גויאבה עדיין לוקחת את העוגה, מבחינת זמני ההכנסה.

למרות שהשווינו רק את ממשקי ה- API של האוספים בדוגמאות הקוד שלנו, Apache Commons בכללותו מציע מגוון גדול יותר של תכונות בהשוואה לגויאבה.

8. מסקנה

במדריך זה השווינו חלק מהפונקציונליות המוצעת על ידי Apache Commons ו- Google Guava, במיוחד בתחום מסגרת האוספים.

כאן רק גירדנו את פני השטח של שתי הספריות להציע.

יתר על כן, זו לא השוואה בין או. כפי שהוכיחו דוגמאות הקוד שלנו, יש תכונות ייחודיות לכל אחד מהשניים, ויכולים להיות מצבים ששניהם יכולים להתקיים יחד.

כמו תמיד, קוד המקור זמין ב- GitHub.


$config[zx-auto] not found$config[zx-overlay] not found