💎 تفاوت equals و compareTo برای مقایسه رشته ها
🔆 هر دو متد برای مقایسه رشته کاربرد دارند ولی این بین تفاوت هایی وجود دارد. شاید بزرگترین تفاوت این باشد که equals ابجکت ها و comareTo حروف را با هم مقایسه میکند. طبق این قضیه میتوان نتیجه گرفت که در مقایسه ی null :
🔆 متد equals فقط دو مقدار false و true را بازگشت میدهد و آنهم زمانیست که مقدار دو رشته برابر یا نابرابر باشد. ضمنا همانطور که اشاره کردیم متد equals در هنگام مقایسه، از رخ دادن خطای NullPointerException جلو گیری میکند.
🔆 متد compareTo با توجه به اسناد جاوا، رشته ها را بصورت حرف به حرف (لغوی / lexographically) و همینطور از نظر طول رشته مقایسه میکند. طبق این مقایسه، این متد سه مقدار صفر، مثبت و منفی را بازگشت میدهد.
🔅مقدار صفر مختص زمانیست که رشته ها هم از لحاظ لغت و هم طول مقدار برابر داشته باشند.
🔅 مقدار منفی مختص زمانیست که رشته اول نسبت به رشته دوم طول کمتری داشته باشد.
🔅مقدار مثبت نیز مختص زمانیست که رشته اول نسبت به رشته دوم طول بیشتری داشته باشد
🔰 مثال:
#equals #string #compareto #lexographically
@pieceJava
🔆 هر دو متد برای مقایسه رشته کاربرد دارند ولی این بین تفاوت هایی وجود دارد. شاید بزرگترین تفاوت این باشد که equals ابجکت ها و comareTo حروف را با هم مقایسه میکند. طبق این قضیه میتوان نتیجه گرفت که در مقایسه ی null :
"foo".equals((String) null)
مقدار فالس را بازگشت میدهد. این در صورتی است که"foo".compareTo( (String) null)
استثنای NullPointerException را به همراه خواهد داشت.🔆 متد equals فقط دو مقدار false و true را بازگشت میدهد و آنهم زمانیست که مقدار دو رشته برابر یا نابرابر باشد. ضمنا همانطور که اشاره کردیم متد equals در هنگام مقایسه، از رخ دادن خطای NullPointerException جلو گیری میکند.
🔆 متد compareTo با توجه به اسناد جاوا، رشته ها را بصورت حرف به حرف (لغوی / lexographically) و همینطور از نظر طول رشته مقایسه میکند. طبق این مقایسه، این متد سه مقدار صفر، مثبت و منفی را بازگشت میدهد.
🔅مقدار صفر مختص زمانیست که رشته ها هم از لحاظ لغت و هم طول مقدار برابر داشته باشند.
🔅 مقدار منفی مختص زمانیست که رشته اول نسبت به رشته دوم طول کمتری داشته باشد.
🔅مقدار مثبت نیز مختص زمانیست که رشته اول نسبت به رشته دوم طول بیشتری داشته باشد
🔰 مثال:
⭕️ System.out.println("Aaaa".compareTo("Aa"));
یک مقدار مثبت را بازگشت میدهد. زیرا رشته اول نسبت به رشته دوم طول بیشتری دارد.⭕️ System.out.println("Aa".compareTo("Aaaaa"));
یک مقدار منفی را برمیگرداند. زیرا رشته دوم نسبت به رشته اول طول بیشتری دارد.⭕️ System.out.println("Aa".compareTo("Aa"));
مقدار صفر را دارد زیرا در این مقایسه رشته ها مقدار برابر را دارند.⭕️ System.out.println("A".compareTo("B"));
در این مثال از آنجا که از نظر لغوی (lexographically) حرف "B" نسبت به حرف "A" در ترتیب الفبا جلوتر قرار گرفته است، خروجی مقدار منفی خواهد بود.#equals #string #compareto #lexographically
@pieceJava
👍4
💎معنی Mutable و Immutable بودن کلاس ها (قابل تغییر و غیر قابل تغییر بودن)
🔅به آبجکت هایی که بعد از ایجاد شدن قابل تغییر هستند، Mutable گفته میشود. برای مثال کلاس Date یا StringBuilder
🔅در مقابل به ابجکت هایی که پس از ایجاد شدن قابل تغییر نیستند، Immutable گفته میشود. برای مثال کلاس String, Integer, Long,...
🔰 نمونه کلاس String:
(در اینباره بیشتر بخوانید)
🔆تفاوت های کلاس های Mutable و Immutable
⭕️در کلاس های Mutable فیلد ها بعد از ایجاد ابجکت قابل تغییر هستند در صورتی که در کلاس های Immutable چنین چیزی ممکن نیست.
⭕️کلاس های Mutable دارای متد هایی برای تغییر مقادیر فیلد ها مانند setter & getter هستند. در صورتی که کلاس های Immutable فقط دارای متد های getter میباشند.
⁉️چرا بعضی از کلاس ها Immutable هستند و یا چرا باید باشند؟
- همانطور که گفتیم مقادیر این کلاس ها غیر قابل تغییر است و از لحاظ مدیریت حافظه بصرفه است.
- کلاس های Immutable اصطلاحا Thread Safe هستند (در محیط های چند نخی (multithreading)) در واقع Thread safety به فرایند امن سازی برنامه در محیط های چند نخی گفته میشود.
🔗 نحوه ایجاد کلاس Immutable
#immutable #mutable #threadsafe #thread_safe #StringBuilder #Date #String
@pieceJava
🔅به آبجکت هایی که بعد از ایجاد شدن قابل تغییر هستند، Mutable گفته میشود. برای مثال کلاس Date یا StringBuilder
🔅در مقابل به ابجکت هایی که پس از ایجاد شدن قابل تغییر نیستند، Immutable گفته میشود. برای مثال کلاس String, Integer, Long,...
🔰 نمونه کلاس String:
String str = "Test";
str.replaceAll("T","s);
System.out.println(str)
;//prints Test
در قطعه کد بالا پس از خروجی گرفتن رشته str خواهید دید که رشته بدون هیچ تغییر خاصی نمایش داده خواهد شد.(در اینباره بیشتر بخوانید)
🔆تفاوت های کلاس های Mutable و Immutable
⭕️در کلاس های Mutable فیلد ها بعد از ایجاد ابجکت قابل تغییر هستند در صورتی که در کلاس های Immutable چنین چیزی ممکن نیست.
⭕️کلاس های Mutable دارای متد هایی برای تغییر مقادیر فیلد ها مانند setter & getter هستند. در صورتی که کلاس های Immutable فقط دارای متد های getter میباشند.
⁉️چرا بعضی از کلاس ها Immutable هستند و یا چرا باید باشند؟
- همانطور که گفتیم مقادیر این کلاس ها غیر قابل تغییر است و از لحاظ مدیریت حافظه بصرفه است.
- کلاس های Immutable اصطلاحا Thread Safe هستند (در محیط های چند نخی (multithreading)) در واقع Thread safety به فرایند امن سازی برنامه در محیط های چند نخی گفته میشود.
🔗 نحوه ایجاد کلاس Immutable
#immutable #mutable #threadsafe #thread_safe #StringBuilder #Date #String
@pieceJava
Telegram
تیکه پاره های جاوا
#چرا
💎چرا رشته ها غیر قابل تغییر یا Immutable هستند؟
در مورد Immutable و Mutable بودن کلاس ها از اینجا بخوانید.
فرض کنید رشته ای بصورت زیر داریم:
String str = "Hello";
حال بوسیله متد concat یک رشته را به رشته فعلی اضافه میکنیم:
str.concat(" World");
و در…
💎چرا رشته ها غیر قابل تغییر یا Immutable هستند؟
در مورد Immutable و Mutable بودن کلاس ها از اینجا بخوانید.
فرض کنید رشته ای بصورت زیر داریم:
String str = "Hello";
حال بوسیله متد concat یک رشته را به رشته فعلی اضافه میکنیم:
str.concat(" World");
و در…
👍3
💎 تفاوت String, StringBuilder , StringBuffer
🔆 جاوا برای دنباله ای از کاراکتر ها (رشته ها) سه کلاس فراهم کرده است: String, StringBuffer, StringBuilder.
همانطور که پیش تر گفتیم رشته ها از کلاس String غیر قابل تغییر یا Immutable هستند. در مقابل کلاس StringBuffer و StringBuilder کلاس های قابل تغییر هستند.
تفاوت های زیادی مابین StringBuilder و StringBuffer وجود دارد که در ادامه بخشی از این تفاوت ها را بیان خواهیم کرد.
1️⃣ا StringBuffer سنکرونایز شده و Thread-safe میباشد. این یعنی دو ترد بصورت همزمان نمیتوانند متد های StringBuffer را صدا بزنند. (در غیر اینصورت موقع استفاده همزمان ترد ها ممکن است نتایج اشتباه بوجود بیاید). از این جهت در محیط های چند نخی (multiple threads) میتواند بهتر عمل کند
2️⃣ا StringBuilder سنکرونایز شده و Thread-safe نیست. این یعنی چند ترد بطور همزمان میتوانند از متد های این کلاس استفاده کنند. از این رو در محیط های تک نخی (single threaded) بهتر میتواند عمل کند.
3️⃣ا StringBuffer نسبت به StringBuilder از کارامدی کمتری برخوردار است
🔰 مثال برای مورد 3:
💬 (برای خوانایی بیشتر، تصویر کد رو هم قرار میدم)
———
☕️@pieceJava
🔆 جاوا برای دنباله ای از کاراکتر ها (رشته ها) سه کلاس فراهم کرده است: String, StringBuffer, StringBuilder.
همانطور که پیش تر گفتیم رشته ها از کلاس String غیر قابل تغییر یا Immutable هستند. در مقابل کلاس StringBuffer و StringBuilder کلاس های قابل تغییر هستند.
تفاوت های زیادی مابین StringBuilder و StringBuffer وجود دارد که در ادامه بخشی از این تفاوت ها را بیان خواهیم کرد.
1️⃣ا StringBuffer سنکرونایز شده و Thread-safe میباشد. این یعنی دو ترد بصورت همزمان نمیتوانند متد های StringBuffer را صدا بزنند. (در غیر اینصورت موقع استفاده همزمان ترد ها ممکن است نتایج اشتباه بوجود بیاید). از این جهت در محیط های چند نخی (multiple threads) میتواند بهتر عمل کند
2️⃣ا StringBuilder سنکرونایز شده و Thread-safe نیست. این یعنی چند ترد بطور همزمان میتوانند از متد های این کلاس استفاده کنند. از این رو در محیط های تک نخی (single threaded) بهتر میتواند عمل کند.
3️⃣ا StringBuffer نسبت به StringBuilder از کارامدی کمتری برخوردار است
🔰 مثال برای مورد 3:
💬 (برای خوانایی بیشتر، تصویر کد رو هم قرار میدم)
public class ITHOOLOO{
public static void main(String[] args){
long startTime = System.currentTimeMillis();
StringBuffer sb = new StringBuffer("IT");
for (int i=0; i<10000; i++){
sb.append("HOOLOO");
}
System.out.println("Time taken by StringBuffer: " +
(System.currentTimeMillis() - startTime) + "ms");
startTime = System.currentTimeMillis();
StringBuilder sb2 = new StringBuilder("IT");
for (int i=0; i<10000; i++){
sb2.append("HOOLOO");
}
System.out.println("Time taken by StringBuilder: " +
(System.currentTimeMillis() - startTime) + "ms");
}
}
//OUTPUT:
// Time taken by StringBuffer: 11ms
// Time taken by StringBuilder: 1ms
#StringBuilder #StringBuffer #String———
☕️@pieceJava
👍4
🔆 تفاوت سرعت و کارایی میان الحاق کردن رشته با + و append از کلاس StringBuilder
↖️ همانطور که میدانید String یک نوع غیر قابل تغییر (Immutable) است اما از طریق StringBuilder میتوانید یک نوع تغییر پذیر از رشته ها ایجاد کنید.
این نکته را هم در ذهن داشته باشید که برای یک رشته فرضا به نام str مادامی که یک رشته را به آن الحاق میکنید، یک آبجکت جدید در String pool ایجاد شده و آدرس آن در str ذخیره میشود. مثلا برای کد زیر
String str = "Hello";
str +=" World";
در خط اول یک رشته "Hello" در String pool ایجاد میشود و در خط بعدی نیز رشته ی جدید "Hello World" در String pool مجددا ایجاد میشود. در نتیجه هر الحاق یک رشته ی جدید را در String pool ایجاد میکند ( مگر اینکه رشته ی الحاقی قبلا در String pool ایجاد شده باشد که در اینصورت jvm آدرس به آن رشته را باز میگرداند و دیگر رشته ی جدیدی ساخته نمیشود. البته این مورد رو بعدا در پست جداگانه و بطور تخصصی تر هم بررسی میکنیم).
اما در حقیقت، الحاق کردن رشته از طریق + یا StringBuilder.append() هر دو به یک صورت انجام میشود و هر دو هنگام کمپایل شدن یک نوع بایت کد را تولید میکنند. این یعنی اگر داشته باشیم:
str = str1 + str2 + str3
این قطعه کد دقیقا معادل تکه کد زیر خواهد بود:
str = new StringBuilder().sb.append(str1).append(str2).append(str3).toString();
به اینصورت که انگار با الحاق کردن چند رشته با +، به نحوی یک نمونه از StringBuilder ایجاد کرده ایم و همه ی رشته ها را با متد append به هم الحاق کرده ایم.
اما مسئله زمانی تفاوت پیدا میکند که بخواهیم در یک حلقه با تعداد تکرار بالا، الحاق را انجام دهیم. برای مثال تکه کد زیر را در نظر بگیرید:
اجرای این تکه کد برای الحاق 100000 کاراکتر شاید به اندازه ی 11000ms (یازده ثانیه) زمان ببرد تا بطور کامل اجرا شود (زمان اجرای این تکه کد روی هر ماشین متفاوت است و ممکن است برای شما کمتر یا بیشتر طول بکشد).
اما اگر از طریق StringBuilder این کار را انجام دهیم:
👈 در واقع در قطعه کد اول، بخاطر خاصیت Immutable بودن رشته ها، هر بار رشته ی جدیدی در String pool ایجاد میشود و آدرس آن به str داده میشود که این میتواند هزینه ی اضافی را تحمیل کند. اما در قطعه کد دوم، فقط یک آبجکت از StringBuilder ایجاد میشود و هر بار کاراکتری به دنباله کاراکتر های قبلی اضافه میشود(در واقع در این کلاس آرایه ای از جنس کاراکتر ها وجود دارد) و تا زمانی که toString را برای این کلاس صدا نزنید، کل کاراکتر ها در همین حالت و بصورت یک دنباله در این ارایه میمانند.
شاید بگویید پیشتر به این موضوع اشاره کردیم که + و append به یک صورت عمل میکنند اما به خاطر داشته باشید که با هر بار + یک نمونه از StringBuilder در heap ایجاد میشود. یعنی برای 100000 تکرار ما 100000 آبجکت ایجاد کرده ایم!
📌نتیجه گیری:
- اگر دستورات کوتاه برای الحاق چند رشته دارید، مستقیم از + استفاده کنید و حالشو ببرید😁
- اگر لازم است که الحاق در چندین مرحله صورت گیرد، پیشنهاد میشود که از StringBuilder استفاده کنید
#String #StringBuilder #concat
————
@PieceJava
↖️ همانطور که میدانید String یک نوع غیر قابل تغییر (Immutable) است اما از طریق StringBuilder میتوانید یک نوع تغییر پذیر از رشته ها ایجاد کنید.
این نکته را هم در ذهن داشته باشید که برای یک رشته فرضا به نام str مادامی که یک رشته را به آن الحاق میکنید، یک آبجکت جدید در String pool ایجاد شده و آدرس آن در str ذخیره میشود. مثلا برای کد زیر
String str = "Hello";
str +=" World";
در خط اول یک رشته "Hello" در String pool ایجاد میشود و در خط بعدی نیز رشته ی جدید "Hello World" در String pool مجددا ایجاد میشود. در نتیجه هر الحاق یک رشته ی جدید را در String pool ایجاد میکند ( مگر اینکه رشته ی الحاقی قبلا در String pool ایجاد شده باشد که در اینصورت jvm آدرس به آن رشته را باز میگرداند و دیگر رشته ی جدیدی ساخته نمیشود. البته این مورد رو بعدا در پست جداگانه و بطور تخصصی تر هم بررسی میکنیم).
اما در حقیقت، الحاق کردن رشته از طریق + یا StringBuilder.append() هر دو به یک صورت انجام میشود و هر دو هنگام کمپایل شدن یک نوع بایت کد را تولید میکنند. این یعنی اگر داشته باشیم:
str = str1 + str2 + str3
این قطعه کد دقیقا معادل تکه کد زیر خواهد بود:
str = new StringBuilder().sb.append(str1).append(str2).append(str3).toString();
به اینصورت که انگار با الحاق کردن چند رشته با +، به نحوی یک نمونه از StringBuilder ایجاد کرده ایم و همه ی رشته ها را با متد append به هم الحاق کرده ایم.
اما مسئله زمانی تفاوت پیدا میکند که بخواهیم در یک حلقه با تعداد تکرار بالا، الحاق را انجام دهیم. برای مثال تکه کد زیر را در نظر بگیرید:
long start = System.currentTimeMillis();
String str = "";
for(int i = 0;i<100000;i++){
str+="*";
}
long finish = System.currentTimeMillis();
System.out.println(finish-start+"ms");
اجرای این تکه کد برای الحاق 100000 کاراکتر شاید به اندازه ی 11000ms (یازده ثانیه) زمان ببرد تا بطور کامل اجرا شود (زمان اجرای این تکه کد روی هر ماشین متفاوت است و ممکن است برای شما کمتر یا بیشتر طول بکشد).
اما اگر از طریق StringBuilder این کار را انجام دهیم:
long start = System.currentTimeMillis();خواهید دید که زمان اجرا کاهش شدیدی پیدا میکند (مثلا 10 میلی ثانیه).
StringBuilder str = new StringBuilder();
for(int i = 0;i<100000;i++){
str.append("*");
}
long finish = System.currentTimeMillis();
System.out.println(finish-start+"ms");
👈 در واقع در قطعه کد اول، بخاطر خاصیت Immutable بودن رشته ها، هر بار رشته ی جدیدی در String pool ایجاد میشود و آدرس آن به str داده میشود که این میتواند هزینه ی اضافی را تحمیل کند. اما در قطعه کد دوم، فقط یک آبجکت از StringBuilder ایجاد میشود و هر بار کاراکتری به دنباله کاراکتر های قبلی اضافه میشود(در واقع در این کلاس آرایه ای از جنس کاراکتر ها وجود دارد) و تا زمانی که toString را برای این کلاس صدا نزنید، کل کاراکتر ها در همین حالت و بصورت یک دنباله در این ارایه میمانند.
شاید بگویید پیشتر به این موضوع اشاره کردیم که + و append به یک صورت عمل میکنند اما به خاطر داشته باشید که با هر بار + یک نمونه از StringBuilder در heap ایجاد میشود. یعنی برای 100000 تکرار ما 100000 آبجکت ایجاد کرده ایم!
📌نتیجه گیری:
- اگر دستورات کوتاه برای الحاق چند رشته دارید، مستقیم از + استفاده کنید و حالشو ببرید😁
- اگر لازم است که الحاق در چندین مرحله صورت گیرد، پیشنهاد میشود که از StringBuilder استفاده کنید
#String #StringBuilder #concat
————
@PieceJava
👍7❤4