מחרוזת נגד StringBuffer נגד StringBuilder

\begin{hebrew}
מחרוזת היא אחת מהמחלקות הנפלאות ביותר ב-Java. מחלקות StringBuffer ו-StringBuilder מספקות שיטות לניהול של מחרוזות. נבחן את ההבחנה בין StringBuffer ל-StringBuilder. StringBuffer נגד StringBuilder הוא שאלה פופולרית בראיונות עבודה ב-Java.

String vs StringBuffer vs StringBuilder

המחרוזת היא אחת מהנושאים החשובים ביותר בראיונות עבודה בקור java. אם אתה כותב תוכנית שמדפיסה משהו בקונסול, אתה משתמש ב-String. המדריך הזה מתמקד בתכונות העיקריות של מחלקת String. לאחר מכן נقار compare את מחלקות StringBuffer ו-StringBuilder.

String in Java

  1. מחלקת String מייצגת מחרוזות תווים, אפשר ליצור מחרוזת בשני אופנים.

    String str = "ABC";
    // או
    String str = new String("ABC");
    
  2. המחרוזת היא לא נעדרת ב-Java. לכן זה מתאים לשימוש בסביבה מרובה-תחומית. אפשר לשתף אותה בין פונקציות משום שאין חשש מאי עקביות בנתונים.</diy14}
    \end{hebrew}
  3. כאשר אנו יוצרים מחרוזת באמצעות גרשיים כפולים, הJVM מחפשת תחילה אחר המחרוזת באותו ערך בבריכת המחרוזות. אם נמצאת, היא מחזירה את ההפניה לאובייקט המחרוזת מהבריכה. אחרת, היא יוצרת את אובייקט המחרוזת בבריכת המחרוזות ומחזירה את ההפניה. הJVM חוסכת הרבה זיכרון על ידי שימוש באותה מחרוזת בתהליכים שונים.

  4. אם משתמשים באופרטור ה־new ליצירת מחרוזת, היא נוצרת בזיכרון ה־heap.

  5. האופרטור + מוטען עבור מחרוזת. ניתן להשתמש בו לחיבור של שתי מחרוזות. אף על פי שבאופן פנימי הוא משתמש ב־StringBuffer לביצוע הפעולה זו.

  6. מחרוזת מחליף את השיטות equals() ו־hashCode(). שתי מחרוזות שוות רק אם להן אותו סדר תווים. שיטת equals() היא רגילה למקרה. אם אתה מחפש בדיקות לא רגילות, אתה צריך להשתמש בשיטה equalsIgnoreCase().

  7. המחרוזת משתמשת בקידוד UTF-16 לקריאת התווים.

  8. מחרוזת היא מחלקה סופית. כל השדות הם סופיים חוץ מ-"private int hash". השדה הזה מכיל את ערך הפונקציה hashCode(). ערך ה-hashcode נחשב רק כאשר שיטת hashCode() נקראת לפעם הראשונה ואז מוקפאת בשדה זה. יתר על כן, ה-hash נוצר על ידי השדות הסופיים של מחלקת String עם חישובים מסוימים. לכן, בכל פעם ששיטת hashCode() נקראת, זה יגרום לאותו פלט. עבור הקורא, זה נראה כאילו חישובים קורים כל פעם, אך בפועל זה מוקפא בשדה ה-hash.

מחרוזת נגד StringBuffer

מאחר שמחרוזת היא לא ניתנת לשינוי ב-Java, בכל פעם שנעשה עיבוד של מחרוזת כמו חיבור, חתימה, וכו', מיוצרת מחרוזת חדשה והמחרוזת הישנה מושלכת לאיסוף אשפה. אלו פעולות כבדות ויוצרות המון אשפה בזיכרון המטמון. לכן ב-Java ניתן להשתמש במחלקות StringBuffer ו- StringBuilder שמספקות פעולות על מחרוזות. StringBuffer ו- StringBuilder הם אובייקטים משתנים ב-Java. הם מספקים את הפעולות append(), insert(), delete(), ו- substring() לעיבוד של מחרוזות.

מחרוזת נגד StringBuilder

מחרוזת ה-StringBuffer הייתה הבחירה היחידה לעיבוד מחרוזות עד לגרסה 1.4 של Java. אך יש לה מזיק אחד – כל השיטות הציבוריות שלה מסונכרנות. StringBuffer מספקת בטיחות לתהליכים אך במחיר ביצועים. ברוב התרחישים, אין לנו צורך בשימוש במחרוזת בסביבה מרובה-תהליך. לכן, ב-Java 1.5 הוזן סוגר חדש, StringBuilder, שדומה ל-StringBuffer אך לא מסונכרן. ל-StringBuffer יש שיטות נוספות כמו substring, length, capacity, trimToSize וכו'. אולם, אלו אינם נחוצים מאחר ויש את כל אלו גם במחרוזת. זו הסיבה שלא יושם את השיטות הללו במחלקת StringBuilder. StringBuffer הוזן ב-Java 1.0 כל עוד ש-StringBuilder הוזן ב-Java 1.5 לאחר חקיקת המגבלות של StringBuffer. אם אתה בסביבה עם תהליכים יחידים או שאין לך דאגה לבטחון מסננכרנת, כדאי להשתמש ב-StringBuilder. בכל מקרה אחר, יש להשתמש ב-StringBuffer לפעולות בטוחות מתיר.

ביצועים של StringBuilder נגד StringBuffer

I am trying to check the effect on performance because of synchronization with a sample program that performs append() on StringBuffer and StringBuilder object for multiple times.

package com.journaldev.java;

import java.util.GregorianCalendar;

public class TestString {

	public static void main(String[] args) {
		System.gc();
		long start=new GregorianCalendar().getTimeInMillis();
		long startMemory=Runtime.getRuntime().freeMemory();
		StringBuffer sb = new StringBuffer();
		//StringBuilder sb = new StringBuilder();
		for(int i = 0; i<10000000; i++){
			sb.append(":").append(i);
		}
		long end=new GregorianCalendar().getTimeInMillis();
		long endMemory=Runtime.getRuntime().freeMemory();
		System.out.println("Time Taken:"+(end-start));
		System.out.println("Memory used:"+(startMemory-endMemory));
	}
}

I ran the same code for the StringBuffer object also to check the time and memory values. I have executed the code 5 times for each case and then calculated the average values.

Value of i StringBuffer (Time, Memory) StringBuilder (Time, Memory)
10,00,000 808, 149356704 633, 149356704
1,00,00,000 7448, 147783888 6179, 147783888

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

מחרוזת נגד StringBuffer נגד StringBuilder

  1. מחרוזת היא לא נעולה, בניגוד ל-StringBuffer ול-StringBuilder שהם מחלקות נעולות.
  2. StringBuffer הוא בטוח לשימוש בקשר עם תהליכים ומסונכרן בעוד StringBuilder אינו. זו הסיבה שבגללה StringBuilder מהיר יותר מ-StringBuffer.
  3. אופרטור החיבור של מחרוזת (+) משתמש פנימית במחלקות StringBuffer או StringBuilder.
  4. לטיפול במחרוזות בסביבה שאינה מרובת תהליכים, יש להשתמש ב-StringBuilder, אחרת להשתמש במחלקת StringBuffer.

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

Source:
https://www.digitalocean.com/community/tutorials/string-vs-stringbuffer-vs-stringbuilder