Java varargs

פורסם בקבוצה
היום נדון בדבר כזה כמו varargs בג'אווה. Varargs - או Variable Arguments - היא טכנולוגיה המאפשרת ליצור שיטות עם מספר שרירותי של ארגומנטים. במאמר זה, נלמד כיצד ליצור שיטות כאלה, נדון מדוע יש צורך ב-varargs ומתי עדיף להשתמש בהם.

מה הם וארגים?

Varargs הם ארגומנטים באורך משתנה: תכונה שהופיעה ב-JDK5. Varargs מאפשרים לנו ליצור שיטות עם מספר שרירותי של ארגומנטים. בגדול, אפשר היה ליצור שיטות כאלה בעבר. נכון, לעשות את זה לא היה נוח במיוחד. בואו ניתן דוגמה. נניח שאנחנו צריכים לכתוב שיטה שתיקח מספר שרירותי של ארגומנטים שלמים ותחבר אותם יחד. Java varargs - 1יש לנו שתי אפשרויות. אפשרות 1 - עומס יתר:
class Calculator {
    int sum(int a, int b){...};
    int sum(int a, int b, int c){...};
    int sum(int a, int b, int c, int d){...};
    int sum(int a, int b, int c, int d, int e){...};
}
אבל יש שתי בעיות עם עומס יתר. ראשית, לא תמיד ברור מתי הגיע הזמן להפסיק, ושנית, זה מסורבל. מערכים טובים יותר. אפשרות 2 - מערכים:
class Calculator {
    int sum(int[] numbers){...};
}
עם מערך זה כבר לא מסורבל, והמערך נראה כאילו כלום... עד שהגיע הזמן לקרוא לשיטה:
public static void main(String... sss) {
    Calculator calculator = new Calculator();

    int[] arguments = new int[7];
    arguments[0] = 1;
    arguments[1] = 10;
    arguments[2] = 123;
    arguments[3] = 234;
    arguments[4] = 6234;
    arguments[5] = 12;
    arguments[6] = 8;

    int sum = calculator.sum(arguments);
}
אנחנו מסכימים, אתה כמובן יכול לכתוב הכל בקצרה יותר. אבל ראשית, אני עדיין רוצה להדגים את חוסר הנוחות בשימוש במערכים כארגומנטים באורך משתנה, ושנית, גם אם נכתוב את זה כך:
int[] arguments = {1,10,123,234,6234,12,8};
int sum = calculator.sum(arguments);
אז עדיין לא ניפטר מכמות הקוד המוגזמת. עם זאת, עם שחרורו של Java 5, נראה שהתכונה של Varargs פותרת את הבעיות הללו. זה אפשר להעביר מספר שרירותי של טיעונים לשיטות. זה נראה בערך כך:
public class Calculator {
    public static void main(String... sss) {
        Calculator calculator = new Calculator();
        int sum = calculator.sum(1,10,123,234,6234,12,8);
    }
    int sum(int... numbers){
       return Arrays.stream(numbers).sum();
    }
}
אז בואו נסכם. Varargs הם ארגומנטים באורך משתנה, תכונה שהופיעה עם שחרורו של Java 5. לאחר מכן, נסקור מקרוב כמה כללים לעבודה עם Varargs.

5 חוקים של וארגס

כלל 1. ארגומנט Vararg (או ארגומנט אורך משתנה/שרירותי) מסומן באליפסיס באופן הבא:
String... words
Integer... numbers
Person... people
Cat... cats
כלל 2. ניתן לציין ארגומנט באורך שרירותי רק כארגומנט לשיטה כלשהי:
void print(String... words)
int sum(Integer... numbers)
void save(Person... people)
void feed(Cat... cats)
כלל 3. כל ארגומנט כזה באורך משתנה בגוף השיטה הוא מערך:
void print(String... words){
    for (int i = 0; i < words.length; i++) {
        System.out.println(words[i]);
    }
}
כלל 4. הארגומנט של Vararg חייב להיות האחרון ברשימת הארגומנטים של השיטה:
void print(String... words, String anotherWord) // - Так нельзя!
void print(String... words, int someNumber) // - Так нельзя!

void print(String anotherWord, String... words) // - Так можно
void print(int someNumber, String... words) // - Так можно
כלל 5: למרות ש-varargs הם מערכים, כאשר קוראים למתודה שלוקחת ארגומנטים באורך משתנה, אין צורך ליצור מערך. מספיק ואף רצוי פשוט לרשום את הטיעונים הנדרשים מופרדים בפסיקים:
public class Main {
    public static void main(String... sss) {
        print("How","же","прекрасно","изучать","Java");
    }

    static void print(String... words){
        for (int i = 0; i < words.length; i++) {
            System.out.println(words[i]);
        }
    }
}

דוגמאות לוארגים

בדוגמה למטה, נכתוב שיטה שלוקחת וארגים המורכבים ממספרים שלמים ומציגה את מספר האלמנטים שעברו ואת הסכום שלהם. בואו נעביר גם מערך וגם סדרה של מספרים שלמים לשיטה זו (שתי האפשרויות תקפות):
public static void main(String... sss) {
    int[] a = new int[100];
    for (int i = 0; i < a.length; i++) {
        a[i] = i;
    }

    sum(a);
    sum(1,2,3,4,5,6,7,8,9,10);
}

static void sum(int... numbers){
    final int length = numbers.length;
    final int sum = Arrays.stream(numbers).sum();
    final String lineSeparator = System.lineSeparator();

    System.out.printf("Кол-во элементов для сложения - %d, сумма - %d%s", length, sum, lineSeparator);
}
לאחר הפעלת התוכנית תוציא:

Кол-во элементов для сложения - 100, сумма - 4950 
Кол-во элементов для сложения - 10, сумма - 55 
ראוי להזכיר שהשיטה System.out.printfמקבלת גם וארגים. אם נסתכל על הקוד של שיטה זו, נראה את זה:
public PrintStream printf(String format, Object ... args) {
    return format(format, args);
}
שיטה נוספת בשימוש נרחב שמקבלת varags היא String.format. הקוד שלו מוצג להלן:
public static String format(String format, Object... args) {
    return new Formatter().format(format, args).toString();
}

מתי להשתמש בוואראגס?

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

סיכום

אז, כיסינו נושא אחר, varargs בג'אווה. הבנו מה זה. תיארנו את הכללים לשימוש ב-varargs. הסתכלנו על דוגמאות של שיטות עם ארגומנטים של אורך שרירותי, וכן דנו מתי עדיף להשתמש ב-varargs ומתי עדיף להימנע משימוש בהם. כשיעורי בית, אתה יכול ליישם את השיטות הבאות:
  • כתוב voidשיטה שלוקחת סדרה של מספרים שלמים ומחזירה את הממוצע האריתמטי שלהם.
  • כתוב voidשיטה שלוקחת סדרה של מחרוזות ומדפיסה את המילה הארוכה ביותר.
  • כתוב שיטה שמחזירה booleanולוקחת משתנה מסוג כארגומנט הראשון String, וסדרה booleanבאורך משתנה כארגומנט הבא.
    ערכים אפשריים Stringהם AND, OR, XOR. אם לארגומנט הראשון יש ערך אחר, על השיטה לזרוק חריג IllegalArgumentException.
    על השיטה לבצע פעולה לוגית (שמצוינת בארגומנט הראשון) על כל אלמנט של הארגומנט varargs ולהחזיר את תוצאת החישוב.
טיעונים ותוצאה לדוגמה:
  • "AND", נכון, נכון, שקר - יחזיר שקר
  • "OR", false, true, false, false - יחזיר אמת
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION