آموزش جاوا

بررسی کلاس String

String in java
نوشته شده توسط نصیر بهرامی دوست

هنوز در کانال تلگرامی neobit عضو نیستید؟ روی این لینک کلیک کنید و همین حالا عضو شوید!

یکی از کلاس های مهم و پرکاربرد در جاوا کلاس String می باشد .به جرات می توان گفت تمام برنامه هایی که تولید می کنیم از این کلاس استفاده می کنند حتی برنامه ابتدایی مانند hello world . دانستن اینکه این کلاس چگونه پیاده سازی شده است و چه رفتارهایی دارد به ما کمک می کند کدهای با کیفیت تری بنویسیم. در این مقاله قصد داریم کلاس جاوا را مورد بررسی قرار دهیم . پس در ادامه با ما همراه باشید.

 

String چیست ؟

ترجمه فارسی String ، رشته می باشد و در حقیقت String یا رشته دنباله ای از کاراکتر می باشد . به طور معمول ما String را به صورت زیر ایجاد می کنیم :

String site = "neobit.ir";

 

محل قرارگیری

کلاس String در پکیج java.lang قرار گرفته است . در این پکیج مهمترین کلاس های جاوا قرار دارند . این پکیج به صورت خودکار توسط compiler در کلاس های دیگر import می‌شود پس برای استفاده از کلاس String و دیگر کلاس های موجود در این پکیج نیاز به نوشتن دستور import نیست . 

 

کلاس String به چه صورت پیاده سازی شده است ؟

در این قسمت می خواهیم بررسی کنیم کلاس String توسط طراحان جاوا چگونه پیاده سازی شده است . همانطور که میدانید هر کلاس از دو قسمت تشکیل شده است . قسمت اول header کلاس جایی که با استفاده از کلمه کلیدی class ، نام کلاس و مشخصات کلاس را تعریف می کنیم و قسمت دوم بدنه (body) کلاس که اعضا کلاس شامل فیلد ها و متدهای کلاس درون آن تعریف می شوند .
ابتدا به بررسی header کلاس String می پردازیم.

header کلاس String به صورت زیر تعریف شده است :

public final class String

implements java.io.Serializable, Comparable<String>, CharSequence {

    //body

}

 

همانطور که مشاهده می کنید این کلاس به صورت final تعریف شده است . این بدان معناست که هیچ کلاسی نمی تواند از String ارث بری کند . در طرف دیگر کلاس String سه اینترفیس Serializable ، Comparable و CharSequence را پیاده سازی کرده است .

CharSequence Interface

از بین اینترفیس های بالا ، اینترفیس CharSequence توسط دو کلاس دیگر StringBuffer و StringBuilder پیاده سازی شده است .CharSequence یک interface یا الگوی پیاده سازی برای ساخت و نمایش دنباله ای از کاراکترها است.

CharSequence Interface

بسیار عالی . بخش header کلاس String را بررسی کردیم . حالا میرسیم به اعضا این کلاس یعنی فیلدها و متدها . ابتدا فیلدها .

در بخش بررسی فیلدها تنها فیلد value را بررسی می کنیم . این فیلد به صورت زیر تعریف شده است:

/** The value is used for character storage. */

private final char value[];

هنگامی که ما یک شی از کلاس String می سازیم ، مقادیر رشته ما در این فیلد ذخیره می شود . همانطور که مشاهده می کنید این فیلد به صورت آرایه تعریف شده است ، یا بهتر است بگوییم آرایه ای از کاراکترها . پس می توان اینگونه نتیجه بگیریم تمام رشته ها آرایه ای از کاراکتر ها هستند و این کاراکترها هستند با کنار هم قرار گرفتن رشته های ما را تشکیل می دهند . 

به علت اینکه این فیلد به صورت آرایه تعریف شده است و یکی از خاصیت های آرایه ها این می باشد که طول آنها قابل تعریف نمی باشد ، بنابراین شما با هر بار تغییر در مقادیر رشته یک رشته جدید ایجاد می کنید . 

 

لیست متدهای کلاس String در جاوا

شماره متد شرح متد
1

char charAt(int index)

اندیس (شماره ی مکان قرارگیری) کاراکتر را به عنوان ورودی گرفته و در خروجی مقدار char متناظر (مقیم در آن اندیس) را برمی گرداند.
2

()int length

طول یا تعداد کاراکترهای موجود در رشته را برمی گرداند.
3

static String format(String format, Object… args)

یک string به عنوان ورودی گرفته و پس از فرمت دهی آن بر اساس پارامتر اول، رشته ی فرمت دهی شده را در خروجی برمی گرداند.
4

static String format(Locale l, String format, Object… args)

رشته ی ورودی را بر اساس زبان کشور تعیین شده (پارامتر Locale) فرمت دهی نموده و آن را در خروجی برمی گرداند.
5

String substring(int beginIndex)

بخشی از کل رشته ورودی را از اندیس مشخص شده استخراج کرده و در خروجی برمی گرداند.
6

String substring(int beginIndex, int endIndex)

بخشی از کل رشته ی ورودی را از اندیس شروع تا اندیس پایان که توسط دو پارامتر مشخص می شوند، استخراج می نماید.
7

boolean contains(CharSequence s)

بررسی می کند آیا کاراکترهای ارسال شده به عنوان آرگومان در رشته ی موردنظر وجود دارند یا خیر. در صورت صحیح بودن مقدار true و در غیر این صورت false را برمی گرداند.
8

static String join(CharSequence delimiter, CharSequence… elements)

دو رشته ی ورودی را به یکدیگر متصل کرده و آن را در خروجی برمی گرداند.
9

static String join(CharSequence delimiter, Iterable elements)

دو رشته ی ورودی را با تفکیک کننده ی تعیین شده (در قالب پارامتر delimiter) به هم متصل کرده و پس از درج تفکیک کننده ی مزبور به ازای هر رشته، رشته ی حاصل را در خروجی برمی گرداند.
10

boolean equals(Object another)

دو رشته را بر اساس محتوای آن بایدیگر مقایسه کرده و در صورتی که حتی یک کاراکتر در دو رشته با هم منطبق نباشد، مقدار بولی false را برمی گرداند.
11

()boolean isEmpty

بررسی می کند آیا رشته ورودی تهی است یا خیر.
12

String concat(String str)

رشته ی ارسال شده به عنوان ورودی را به انتهای رشته ی مورد نظر متصل کرده و آن را در خروجی بر می گرداند.
13

String replace(char old, char new)

تمامی نمونه های char را در رشته ی مورد نظر پیدا کرده و آن را با مقدار جدید (پارامتر ورودی دوم) جایگزین می کند.
14

String replace(CharSequence old, CharSequence new)

تمامی نمونه های char در رشته ی مورد نظر (یا CharSequence) را پیدا کرده آن ها را با مقدار جدید جایگزین می کند.
15

static String equalsIgnoreCase(String another)

دو رشته را با یکدیگر مقایسه کرده و در مقایسه ی آن ها نسبت به کوچک و بزرگی حروف حساس نمی باشد.
16

String[] split(String regex)

یک رشته را بر اساس مقدار پارامتر (الگویی که کاراکتر تجزیه را مشخص می کند) regex تجزیه (تکه تکه) کرده و آن را در خروجی مانند یک آرایه از کاراکترها برمی گرداند.
17

String[] split(String regex, int limit)

رشته ی ورودی را بر اساس مقدار regex تجزیه کرده و سپس با توجه به مقدار پارامتر دوم (limit) تعداد مشخصی از زیر رشته ها را در قالب آرایه برمی گرداند.
18

()String intern

رشته ی مورد نظر را با فرمت استاندارد و متعارف برمی گرداند.

با استفاده از این تابع می توان رشته ی مورد نظر را که فقط با کلیدواژه ی new از آن در حافظه ی heap نمونه سازی شده را از ناحیه ی pool حافظه فراخوانی کرد.

19

int indexOf(int ch)

اندیس مقدار char مورد نظر را برمی گرداند.
20

int indexOf(int ch, int fromIndex)

اندیس متناظر مقدار char، ارسال شده به عنوان آرگومان اول را با توجه به اندیس شروع که توسط پارامتر دوم مشخص می شود، برمی گرداند.
21

int indexOf(String substring)

اندیس متناظر زیر رشته ی ارسال شده به عنوان آرگومان را برمی گرداند.
22

int indexOf(String substring, int fromIndex)

اندیس زیررشته ی ارسال شده به عنوان آرگومان را با توجه به مقدار پارامتر دوم که اندیس شروع را تعیین می کند، برمی گرداند.
23

()String toLowerCase

رشته ی ورودی را به حروف کوچک تبدیل کرده و در خروجی برمی گرداند.
24

String toLowerCase(Locale l)

رشته ی ورودی را با توجه به زبان محلی، تعیین شده توسط پارامتر locale، به حروف کوچک تبدیل کرده و در خروجی برمی گرداند.
25

()String toUpperCase

رشته ی ورودی را به حروف بزرگ تبدیل کرده و آن را در خروجی برمی گرداند.
26

String toUpperCase(Locale l)

رشته ی ورودی را با توجه به زبان محلی، تعیین شده توسط پارامتر locale، به حروف بزرگ تبدیل کرده و آن را در خروجی برمی گرداند.
27

()String trim

فضای خالی را از ابتدا و انتهای رشته ی ورودی حذف کرده و رشته ی ویرایش شده را برمی گرداند.
28

static String valueOf(int value)

مقدار ورودی را به رشته تبدیل کرده و آن را در خروجی برمی گرداند.

 

روش های ایجاد String

به طور کلی دو روش برای ایجاد شی ( Object ) از کلاس String وجود دارد .

روش اول : به وسیله لیترال (منظور قرار دادن کاراکترها بین دابل کوتیشن ( “” ) می باشد)

روش دوم : با استفاده از کلید واژه new 

این دو روش هم در ظاهر و هم در باطن ( پشت صحنه) با هم متفاوت هستند . با هم به بررسی این دو روش می پردازیم . 

ایجاد String با استفاده از لیترال

برای درک بهتر این روش ابتدا پیشنهاد می کنم مقاله لیترال چیست را مطالعه کنید . این روش که یکی از متداول ترین روش های ایجاد String است . الگو ایجاد String با این روش به صورت زیر است :

<String_Type> <string_variable> = "<sequence_of_string>";

مثال :

String str = "neobit";

 

هر بار که رشته ای با استفاده از لیترال ایجاد می کنیم ، جاوا محلی از حافظه برنامه به نام string constant pool را بررسی می کند . اگر مقدار رشته در این محل از حافظه وجود داشته باشد ، reference رشته برگردانده می شود  در غیر این صورت یک نمونه ( instance ) از رشته ساخته می شود و در string constant pool قرار داده می شود . به طور مثال :

String s1="Welcome"; 
String s2="Welcome";//It doesn't create a new instance

String Pool

در مثال بالا، تنها یک آبجکت از جنس string ساخته می شود . ابتدا JVM هیچ آبجکتی از جنس string که دارای مقدار “welcome” باشد در constant pool پیدا نمی کند و به همین خاطر یک آبجکت جدید ایجاد می نماید. پس از آن، آبجکتی از جنس string که حاوی مقدار “Welcome” می باشد را در pool یافته، اما این بار دوباره یک آبجکت جدید از نوع یکسان ایجاد نمی کند، بلکه اشاره گری (reference) به همان نمونه را برمی گرداند.

 

ایجاد String با عملگر new

الگو ایجاد String با عملگر new مانند ایجاد یک شی به صورت زیر است :

String site = new String(“neobit.ir”);

زمانیکه ما String را با عملگر new ایجاد می کنیم ، کامپایلر جاوا یک شی جدید ایجاد خواهد کرد و آن را در قسمت Heap حافظه ذخیره می کند . هر رشته ای که با این روش ایجاد می شود در منطقه دیگری از حافظه و دارای آدرس مخصوص به خودش می باشد . برای درک بهتر موضوع به مثال زیر دقت کنید : 

String first = "neobit";

String second = new String("neobit");

System.out.println(first == second); // False

همانطور که مشاهده می کنید نتیجه برخلاف انتظار ما false می باشد  . بدین معنی که دو String دارای آدرس های متفاوتی هستند و در یک محل  از حافظه ذخیره نشده اند . 

 

انتقال دستی String به Constant Pool

جاوا این امکان را در اختیار ما قرار داده است تا با فراخوانی متد intern از کلاس String ، رشته ایجاد شده با عملگر new را وارد constant pool کنیم. با فراخوانی متد intern جاوا reference رشته را در constant pool قرار می دهد و JVM در صورت نیاز reference را برای ما بر می گرداند . دقت کنید String های ایجاد شده با روش لیترال نیازی به استفاده از این متد intern نیست . برای درک موضوع به مثال زیر دقت کنید :

String constantString = "interned neobit";
String newString = new String("interned neobit");

System.out.println(constantString == newString);//false

String internedString = newString.intern();

System.out.println(constantString == internedString);//true

 

منابع + ، +

دربارۀ نویسنده

نصیر بهرامی دوست

پاسخ شما به این دیدگاه