JavaRush /جاوا بلاگ /Random-UR /جاوا میں سٹرنگز (کلاس java.lang.String)
Viacheslav
سطح

جاوا میں سٹرنگز (کلاس java.lang.String)

گروپ میں شائع ہوا۔

تعارف

پروگرامر کا راستہ ایک پیچیدہ اور طویل عمل ہے۔ اور زیادہ تر معاملات میں یہ ایک ایسے پروگرام سے شروع ہوتا ہے جو اسکرین پر ہیلو ورلڈ کو دکھاتا ہے۔ جاوا اس سے مستثنیٰ نہیں ہے (سبق دیکھیں: "ہیلو ورلڈ!" ایپلیکیشن )۔ جیسا کہ ہم دیکھ سکتے ہیں، پیغام آؤٹ پٹ ہے System.out.println("Hello World!"); اگر آپ Java API کو دیکھیں تو System.out.println طریقہ String کو ان پٹ پیرامیٹر کے طور پر لیتا ہے ۔ اس قسم کے ڈیٹا پر بات کی جائے گی۔

حروف کی ترتیب کے طور پر سٹرنگ

دراصل، انگریزی سے ترجمہ شدہ String ایک سٹرنگ ہے۔ یہ ٹھیک ہے، String قسم ٹیکسٹ سٹرنگ کی نمائندگی کرتی ہے۔ ٹیکسٹ سٹرنگ کیا ہے؟ ٹیکسٹ سٹرنگ حروف کی ترتیب شدہ ترتیب کی ایک قسم ہے جو ایک دوسرے کی پیروی کرتے ہیں۔ علامت چار ہے۔ تسلسل - ترتیب۔ تو ہاں، بالکل درست، String کا نفاذ ہے java.lang.CharSequence۔ اور اگر آپ خود String کلاس کے اندر دیکھیں تو اس کے اندر حروف کی ایک صف سے زیادہ کچھ نہیں ہے: private final char value[]; اس کا java.lang.CharSequenceکافی آسان معاہدہ ہے:
جاوا میں سٹرنگز (کلاس java.lang.String) - 1
ہمارے پاس عناصر کی تعداد حاصل کرنے، ایک مخصوص عنصر حاصل کرنے اور عناصر کا ایک سیٹ حاصل کرنے کا طریقہ ہے + toString طریقہ خود، جو اسے واپس کر دے گا) جاوا 8 میں ہمارے پاس آنے والے طریقوں کو سمجھنا زیادہ دلچسپ ہے، اور یہ ہے : chars()اور codePoints() اوریکل کے ٹیوٹوریل سے یاد کریں " Primitive Data " Types " وہ چار ہے single 16-bit Unicode character۔ یعنی بنیادی طور پر char ایک قسم ہے جو ایک int (32 بٹس) کے سائز کا نصف ہے جو 0 سے 65535 تک کے اعداد کو ظاہر کرتا ہے (اعشاریہ اقدار دیکھیں) ASCII ٹیبل میں )۔ یعنی اگر ہم چاہیں تو ہم چار کو بطور int کی نمائندگی کر سکتے ہیں۔ اور جاوا 8 نے اس کا فائدہ اٹھایا۔ جاوا کے ورژن 8 کے ساتھ شروع کرتے ہوئے، ہمارے پاس IntStream ہے - قدیم انٹس کے ساتھ کام کرنے کا سلسلہ۔ لہٰذا، charSequence میں ایک IntStream حاصل کرنا ممکن ہے جس میں یا تو حروف یا codePoints کی نمائندگی ہو۔ اس سے پہلے کہ ہم ان کی طرف بڑھیں، ہم اس نقطہ نظر کی سہولت کو ظاہر کرنے کے لیے ایک مثال دیکھیں گے۔ آئیے ٹیوٹوریل پوائنٹ آن لائن جاوا کمپائلر استعمال کریں اور کوڈ پر عمل کریں:
public static void main(String []args){
        String line = "aaabccdddc";
        System.out.println( line.chars().distinct().count() );
}
اب آپ اس آسان طریقے سے متعدد منفرد علامتیں حاصل کر سکتے ہیں۔

کوڈپوائنٹس

تو، ہم نے حروف کے بارے میں دیکھا۔ اب یہ واضح نہیں ہے کہ یہ کس قسم کے کوڈ پوائنٹس ہیں۔ کوڈپوائنٹ کا تصور ظاہر ہوا کیونکہ جب جاوا نمودار ہوا، 16 بٹس (آدھا انٹ) ایک کردار کو انکوڈ کرنے کے لیے کافی تھے۔ لہذا، جاوا میں چار کو UTF-16 فارمیٹ ("یونیکوڈ 88" تفصیلات) میں دکھایا گیا ہے۔ بعد میں، یونیکوڈ 2.0 ظاہر ہوا، جس کا تصور ایک کردار کو بطور سروگیٹ جوڑا (2 حروف) پیش کرنا تھا۔ اس سے ہمیں ممکنہ اقدار کی حد کو ایک int ویلیو تک بڑھانے کا موقع ملا۔ مزید تفصیلات کے لیے، اسٹیک اوور فلو دیکھیں: " کوڈ پوائنٹ سے چار کا موازنہ؟ " UTF-16 کا ذکر JavaDoc میں کریکٹر کے لیے بھی کیا گیا ہے ۔ وہاں، JavaDoc میں، یہ کہا جاتا ہے کہ: In this representation, supplementary characters are represented as a pair of char values, the first from the high-surrogates range, (\uD800-\uDBFF), the second from the low-surrogates range (\uDC00-\uDFFF). اسے معیاری حروف تہجی میں دوبارہ پیش کرنا کافی مشکل (اور شاید ناممکن بھی) ہے۔ لیکن علامتیں حروف اور اعداد پر ختم نہیں ہوتیں۔ جاپان میں وہ ایموجی کے طور پر انکوڈ کرنے میں اتنی مشکل چیز لے کر آئے - آئیڈیوگرامس اور ایموٹیکنز کی زبان۔ ویکیپیڈیا پر اس کے بارے میں ایک دلچسپ مضمون ہے: “ ایموجی ”۔ آئیے ایک ایموجی کی مثال تلاش کرتے ہیں، مثال کے طور پر یہ: “ ایموجی گھوسٹ ”۔ جیسا کہ ہم دیکھ سکتے ہیں، اسی کوڈپوائنٹ کی بھی وہاں نشاندہی کی گئی ہے (قدر = U+1F47B)۔ یہ ہیکساڈیسیمل فارمیٹ میں اشارہ کیا گیا ہے۔ اگر ہم اعشاریہ نمبر میں تبدیل کرتے ہیں تو ہمیں 128123 ملتا ہے۔ یہ 16 بٹس سے زیادہ اجازت دیتے ہیں (یعنی 65535 سے زیادہ)۔ آئیے اسے کاپی کریں:
جاوا میں سٹرنگز (کلاس java.lang.String) - 2
بدقسمتی سے، JavaRush پلیٹ فارم متن میں ایسے حروف کی حمایت نہیں کرتا ہے۔ لہذا، نیچے دی گئی مثال میں آپ کو String میں ایک قدر داخل کرنے کی ضرورت ہوگی۔ لہذا، اب ہم ایک سادہ ٹیسٹ کو سمجھیں گے:
public static void main(String []args){
	    String emojiString = "Вставте сюда эмоджи через ctrl+v";
	    //На один emojiString приходится 2 чара (т.к. не влезает в 16 бит)
	    System.out.println(emojiString.codePoints().count()); //1
	    System.out.println(emojiString.chars().count()); //2
}
جیسا کہ آپ دیکھ سکتے ہیں، اس معاملے میں 1 کوڈپوائنٹ 2 حروف کے لیے جاتا ہے۔ یہ جادو ہے۔

کردار

جیسا کہ ہم نے اوپر دیکھا، جاوا میں سٹرنگز چار پر مشتمل ہیں۔ ایک قدیم قسم آپ کو ایک قدر ذخیرہ کرنے کی اجازت دیتی ہے، لیکن java.lang.Characterقدیم قسم کے اوپر ایک ریپر آپ کو اس علامت کے ساتھ بہت سے مفید کام کرنے کی اجازت دیتا ہے۔ مثال کے طور پر، ہم سٹرنگ کو بڑے میں تبدیل کر سکتے ہیں:
public static void main(String[] args) {
    String line = "организация объединённых наций";
    char[] chars = line.toCharArray();
    for (int i = 0; i < chars.length; i++) {
        if (i == 0 || chars[i - 1] == ' ') {
            chars[i] = Character.toUpperCase(chars[i]);
        }
    }
    System.out.println(new String(chars));
}
ٹھیک ہے، مختلف دلچسپ چیزیں: isAlphabetic(), isLetter(), isSpaceChar(), isDigit(), isUpperCase(), isMirrored()(مثال کے طور پر، بریکٹ۔ '('ایک آئینے کی تصویر ہے')')۔

سٹرنگ پول

جاوا میں سٹرنگز ناقابل تغیر ہیں، یعنی مستقل۔ یہ java.lang.String کلاس کے JavaDoc میں بھی اشارہ کیا گیا ہے ۔ دوسرا، اور یہ بھی بہت اہم، تاروں کو لٹریلز کے طور پر بیان کیا جا سکتا ہے:
String literalString = "Hello, World!";
String literalString = "Hello, World!";
یعنی کوئی بھی حوالہ دیا گیا تار، جیسا کہ اوپر بتایا گیا ہے، دراصل ایک آبجیکٹ ہے۔ اور یہ سوال پیدا کرتا ہے - اگر ہم اکثر سٹرنگز کا استعمال کرتے ہیں اور وہ اکثر ایک جیسے ہو سکتے ہیں (مثال کے طور پر متن "خرابی" یا "کامیابی سے")، تو کیا اس بات کو یقینی بنانے کا کوئی طریقہ ہے کہ ہر بار سٹرنگز نہ بنیں؟ ویسے، ہمارے پاس ابھی بھی Maps موجود ہے، جہاں کلید ایک تار ہو سکتی ہے۔ پھر ہمارے پاس یقینی طور پر ایک ہی تار مختلف اشیاء نہیں ہو سکتے، ورنہ ہم نقشہ سے آبجیکٹ حاصل نہیں کر پائیں گے۔ جاوا ڈویلپرز نے سوچا، سوچا اور اسٹرنگ پول کے ساتھ آئے۔ یہ وہ جگہ ہے جہاں سٹرنگز کو ذخیرہ کیا جاتا ہے، آپ اسے سٹرنگ کیش کہہ سکتے ہیں۔ تمام لائنیں خود وہاں ختم نہیں ہوتی ہیں، لیکن صرف وہ لائنیں جو کوڈ میں لفظی طور پر بیان کی گئی ہیں۔ آپ خود پول میں ایک لائن شامل کر سکتے ہیں، لیکن بعد میں اس پر مزید۔ تو، میموری میں ہمارے پاس یہ کیش کہیں موجود ہے۔ ایک منصفانہ سوال: یہ پول کہاں واقع ہے؟ اس کا جواب اسٹیک اوور فلو پر پایا جا سکتا ہے: " جاوا کا سٹرنگ کنسٹنٹ پول کہاں رہتا ہے، ہیپ یا اسٹیک؟ " یہ ہیپ میموری میں ایک خاص رن ٹائم کنسٹنٹ پول ایریا میں واقع ہے۔ رن ٹائم کنسٹنٹ پول اس وقت مختص کیا جاتا ہے جب میتھڈ ایریا سے ورچوئل مشین کے ذریعہ کلاس یا انٹرفیس بنایا جاتا ہے - ہیپ میں ایک خاص علاقہ جس تک جاوا ورچوئل مشین کے اندر موجود تمام تھریڈز تک رسائی حاصل ہوتی ہے۔ سٹرنگ پول ہمیں کیا دیتا ہے؟ اس کے کئی فوائد ہیں:
  • ایک ہی قسم کی اشیاء نہیں بنائی جائیں گی۔
  • حوالہ کے لحاظ سے موازنہ برابر کے ذریعے کریکٹر بہ کریکٹر موازنہ سے زیادہ تیز ہے۔
لیکن اگر ہم تخلیق شدہ آبجیکٹ کو اس کیشے میں ڈالنا چاہتے ہیں تو کیا ہوگا؟ پھر، ہمارے پاس ایک خاص طریقہ ہے: String.intern یہ طریقہ سٹرنگ پول میں ایک سٹرنگ جوڑتا ہے۔ یہ بات قابل غور ہے کہ یہ صرف ایک صف کی شکل میں کسی قسم کا کیش نہیں ہے (جیسا کہ انٹیجرز کے لیے)۔ انٹرن طریقہ کو "مقامی" کے طور پر بیان کیا گیا ہے۔ اس کا مطلب یہ ہے کہ طریقہ بذات خود دوسری زبان (زیادہ تر C++) میں لاگو ہوتا ہے۔ جاوا کے بنیادی طریقوں کی صورت میں، JVM سطح پر ان پر مختلف دیگر اصلاحیں لاگو کی جا سکتی ہیں۔ عام طور پر، یہاں جادو ہو جائے گا. انٹرن کے بارے میں درج ذیل پوسٹ کو پڑھنا دلچسپ ہے: https://habr.com/post/79913/#comment_2345814 اور یہ ایک اچھا خیال لگتا ہے۔ لیکن اس کا ہم پر کیا اثر پڑے گا؟ لیکن اس کا واقعی اثر پڑے گا)
public static void main(String[] args) {
    String test = "literal";
    String test2 = new String("literal");
    System.out.println(test == test2);
}
جیسا کہ آپ دیکھ سکتے ہیں، لائنیں ایک جیسی ہیں، لیکن نتیجہ غلط ہوگا۔ اور سب اس لیے کہ == قدر کے لحاظ سے نہیں بلکہ حوالہ سے موازنہ کرتا ہے۔ اور یہ اس طرح کام کرتا ہے:
public static void main(String[] args) {
    String test = "literal";
    String test2 = new String("literal").intern();
    System.out.println(test == test2);
}
بس نوٹ کریں کہ ہم اب بھی نئی String بنائیں گے۔ یعنی، انٹرن ہمیں کیشے سے ایک سٹرنگ واپس کرے گا، لیکن اصل سٹرنگ جسے ہم نے کیشے میں تلاش کیا تھا، اسے صفائی کے لیے باہر پھینک دیا جائے گا، کیونکہ اس کے بارے میں کوئی اور نہیں جانتا. یہ واضح طور پر وسائل کا ایک غیر ضروری استعمال ہے =( اس لیے، آپ کو ہمیشہ مساوی کا استعمال کرتے ہوئے تاروں کا موازنہ کرنا چاہیے تاکہ ممکنہ حد تک غلطیوں کا پتہ لگانا اچانک اور مشکل سے بچا جا سکے۔
public static void main(String[] args) {
    String test = "literal";
    String test2 = new String("literal").intern();
    System.out.println(test.equals(test2));
}
Equals ایک کریکٹر بہ کریکٹر سٹرنگ موازنہ کرتا ہے۔

جوڑنا

جیسا کہ ہمیں یاد ہے، لائنیں شامل کی جا سکتی ہیں۔ اور جیسا کہ ہمیں یاد ہے، ہماری تاریں ناقابل تغیر ہیں۔ تو پھر یہ کیسے کام کرتا ہے؟ یہ ٹھیک ہے، ایک نئی لائن بنائی گئی ہے، جو شامل کی جانے والی اشیاء کی علامتوں پر مشتمل ہے۔ اس کے ایک ملین ورژن ہیں کہ پلس کنکٹنیشن کیسے کام کرتا ہے۔ کچھ لوگ سوچتے ہیں کہ ہر بار کوئی نئی چیز ہو گی، دوسروں کا خیال ہے کہ کچھ اور ہو گا۔ لیکن صرف ایک شخص صحیح ہو سکتا ہے۔ اور یہ کہ کوئی javac مرتب کرنے والا ہے۔ آئیے آن لائن کمپائلر سروس استعمال کریں اور چلائیں:
public class HelloWorld {

    public static void main(String[] args) {
        String helloMessage = "Hello, ";
        String target = "World";
        System.out.println(helloMessage + target);
    }

}
اب آئیے اسے زپ آرکائیو کے طور پر محفوظ کریں، اسے ایک ڈائرکٹری میں نکالیں اور عمل کریں: javap –c HelloWorld اور یہاں ہم سب کچھ تلاش کرتے ہیں:
جاوا میں سٹرنگز (کلاس java.lang.String) - 3
ایک لوپ میں، یقیناً، بہتر ہے کہ خود StringBuilder کے ذریعے کنکٹنیشن کریں۔ اور کسی قسم کے جادو کی وجہ سے نہیں، بلکہ اس لیے کہ StringBuilder سائیکل سے پہلے تخلیق ہو، اور سائیکل میں ہی صرف ضمیمہ ہوتا ہے۔ ویسے یہاں ایک اور دلچسپ بات ہے۔ ایک بہترین مضمون ہے: " جاوا میں اسٹرنگ پروسیسنگ۔ حصہ I: String, StringBuffer, StringBuilder ۔" تبصرے میں بہت ساری مفید معلومات۔ مثال کے طور پر، یہ واضح کیا گیا ہے کہ جب کسی منظر کو جوڑتے ہوئے، new StringBuilder().append()...toString()اندرونی اصلاح اثر میں ہوتی ہے، جو -XX:+OptimizeStringConcat آپشن کے ذریعے ریگولیٹ ہوتی ہے، جو بطور ڈیفالٹ فعال ہوتا ہے۔ اندرونی - "اندرونی" کے طور پر ترجمہ کیا گیا ہے۔ JVM ایسی چیزوں کو ایک خاص طریقے سے ہینڈل کرتا ہے، انہیں مقامی کے طور پر پروسیس کرتا ہے، صرف JNI کے اضافی اخراجات کے بغیر۔ مزید پڑھیں: " HotSpot VM میں اندرونی طریقے

StringBuilder اور StringBuffer

جیسا کہ ہم نے اوپر دیکھا، StringBuilder ایک بہت مفید ٹول ہے۔ تاریں ناقابل تغیر ہیں، یعنی ناقابل تغیر اور میں اسے فولڈ کرنا چاہتا ہوں۔ لہذا، ہماری مدد کے لیے ہمیں 2 کلاسز دی گئی ہیں: StringBuilder اور StringBuffer۔ دونوں کے درمیان بنیادی فرق یہ ہے کہ StringBuffer JDK1.0 میں متعارف کرایا گیا تھا، جبکہ StringBuilder جاوا 1.5 میں StringBuffer کے غیر مطابقت پذیر ورژن کے طور پر آیا تھا تاکہ غیر ضروری طریقہ کار کی مطابقت پذیری کے بڑھتے ہوئے اوور ہیڈ کو ختم کیا جا سکے۔ یہ دونوں کلاسز خلاصہ کلاس AbstractStringBuilder کے نفاذ ہیں - حروف کی ایک تغیر پذیر ترتیب۔ چارمز کی ایک صف اندر ذخیرہ کی جاتی ہے، جسے اصول کے مطابق بڑھایا جاتا ہے: value.length * 2 + 2۔ پہلے سے طے شدہ طور پر، StringBuilder کا سائز (صلاحیت) 16 ہے۔

موازنہ

تاروں کا موازنہ کیا جا سکتا ہے، یعنی compareTo طریقہ کو نافذ کریں۔ یہ کردار بہ کریکٹر موازنہ کا استعمال کرتے ہوئے کیا جاتا ہے۔ دلچسپ بات یہ ہے کہ کم از کم لمبائی دو تاروں سے منتخب کی جاتی ہے اور اس پر ایک لوپ لگایا جاتا ہے۔ لہذا، compareTo یا تو پہلے بے مثال حروف کی int اقدار کے درمیان فرق کو سب سے چھوٹی سٹرنگ کی لمبائی تک واپس کر دے گا، یا سٹرنگ کی لمبائی کے درمیان فرق واپس کر دے گا اگر تمام حروف کم از کم سٹرنگ کی لمبائی میں مماثل ہوں۔ اس موازنہ کو "لغت نگاری" کہا جاتا ہے۔

جاوا سٹرنگز کے ساتھ کام کرنا

اسٹرنگ کے بہت سے مفید طریقے ہیں:
جاوا میں سٹرنگز (کلاس java.lang.String) - 4
تاروں کے ساتھ کام کرنے کے لیے بہت سے کام ہیں۔ مثال کے طور پر، کوڈنگ بیٹ پر ۔ کورسرا پر ایک کورس بھی ہے: " سٹرنگس پر الگورتھم

نتیجہ

یہاں تک کہ اس طبقے کا ایک مختصر جائزہ بھی متاثر کن جگہ لیتا ہے۔ اور یہ سب کچھ نہیں ہے۔ میں JPoint 2015 کی رپورٹ دیکھنے کی انتہائی سفارش کرتا ہوں: Alexey Shipilev - Catechism java.lang.String
#ویاچسلاو
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION