1. StringTokenizerক্লাস

এবং এখন আরও কয়েকটি সাধারণ পরিস্থিতিতে স্ট্রিংগুলির সাথে কাজ করা জড়িত। আপনি কিভাবে একটি স্ট্রিংকে কয়েকটি অংশে বিভক্ত করবেন? এই কাজ করার বিভিন্ন উপায় আছে।

split()পদ্ধতি

একটি স্ট্রিংকে একাধিক অংশে বিভক্ত করার প্রথম উপায় হল split()পদ্ধতিটি ব্যবহার করা। একটি নিয়মিত অভিব্যক্তি যা একটি বিশেষ সীমাবদ্ধ স্ট্রিংকে সংজ্ঞায়িত করে একটি যুক্তি হিসাবে পাস করা আবশ্যক৷ জাভা মাল্টিথ্রেডিং কোয়েস্টে রেগুলার এক্সপ্রেশন কী তা আপনি শিখবেন ।

উদাহরণ:

কোড ফলাফল
String str = "Good news everyone!";
String[] strings = str.split("ne");
System.out.println(Arrays.toString(strings));
ফলাফল তিনটি স্ট্রিং একটি অ্যারে হবে:
["Good ", "ws everyo", "!"]

সহজ, কিন্তু কখনও কখনও এই পদ্ধতির অত্যধিক হয়. যদি অনেকগুলি ডিলিমিটার থাকে (উদাহরণস্বরূপ, স্পেস, নিউলাইন অক্ষর, ট্যাব, পিরিয়ড), তাহলে আপনাকে একটি বরং জটিল রেগুলার এক্সপ্রেশন তৈরি করতে হবে। এটি পড়া কঠিন এবং তাই সংশোধন করা কঠিন।

StringTokenizerক্লাস

জাভার একটি বিশেষ শ্রেণী রয়েছে যার পুরো কাজ হল একটি স্ট্রিংকে সাবস্ট্রিংয়ে বিভক্ত করা।

এই শ্রেণীটি রেগুলার এক্সপ্রেশন ব্যবহার করে না: পরিবর্তে, আপনি কেবল সীমানা বিশিষ্ট একটি স্ট্রিং-এ পাস করেন। এই পদ্ধতির সুবিধা হল যে এটি পুরো স্ট্রিংটিকে একবারে টুকরো টুকরো করে দেয় না, বরং শুরু থেকে শেষ পর্যন্ত একবারে একটি ধাপে চলে যায়।

ক্লাসের একটি কনস্ট্রাক্টর এবং দুটি গুরুত্বপূর্ণ পদ্ধতি রয়েছে। আমরা কন্সট্রাকটরকে একটি স্ট্রিং পাস করি যা আমরা অংশে বিভক্ত করি, এবং একটি স্ট্রিং যা সীমাবদ্ধ অক্ষরের একটি সেট নিয়ে গঠিত।

পদ্ধতি বর্ণনা
String nextToken()
পরবর্তী সাবস্ট্রিং প্রদান করে
boolean hasMoreTokens()
আরও সাবস্ট্রিং আছে কিনা তা পরীক্ষা করে।

এই ক্লাসটি একরকম স্ক্যানার ক্লাসের স্মরণ করিয়ে দেয়, যার রয়েছে nextLine()এবং hashNextLine()পদ্ধতিও।

আপনি এই কমান্ড দিয়ে একটি StringTokenizerবস্তু তৈরি করতে পারেন:

StringTokenizer name = new StringTokenizer(string, delimiters);

যেখানে stringস্ট্রিংকে ভাগে ভাগ করতে হবে। এবং delimitersএকটি স্ট্রিং, এবং এটির প্রতিটি অক্ষর একটি বিভাজক হিসাবে বিবেচিত হয়। উদাহরণ:

কোড কনসোল আউটপুট
String str = "Good news everyone!";

StringTokenizer tokenizer = new StringTokenizer(str,"ne");
while (tokenizer.hasMoreTokens())
{
   String token = tokenizer.nextToken();
   System.out.println(token);
}
Good 
ws 
v
ryo
!

দ্রষ্টব্য যে স্ট্রিং এর প্রতিটি অক্ষর StringTokenizerকনস্ট্রাক্টরের কাছে দ্বিতীয় স্ট্রিং হিসাবে পাস করা একটি বিভাজক হিসাবে বিবেচিত হয়।



2. String.format()পদ্ধতি এবং StringFormatterশ্রেণী

স্ট্রিং ক্লাসের আরেকটি আকর্ষণীয় পদ্ধতি হল format()

ধরা যাক আপনার কাছে ডেটা সংরক্ষণের বিভিন্ন ভেরিয়েবল রয়েছে। আপনি কিভাবে এক লাইনে পর্দায় তাদের প্রদর্শন করবেন? উদাহরণস্বরূপ, আমাদের কাছে কিছু ডেটা (বাম কলাম) এবং পছন্দসই আউটপুট (ডান কলাম):

কোড কনসোল আউটপুট
String name = "Amigo";
int age = 12;
String friend = "Diego";
int weight = 200;
User = {name: Amigo, age: 12 years, friend: Diego, weight: 200 kg.}

আপনার কোড সম্ভবত এই মত কিছু দেখতে হবে:

প্রোগ্রাম কোড
String name = "Amigo";
int age = 12;
String friend = "Diego";
int weight = 200;

System.out.println("User = {name: " + name + ", age:" + age + " years, friend: " + friend+", weight: " + weight + " kg.}");

এই ধরনের কোড খুব পঠনযোগ্য নয়। এবং যদি পরিবর্তনশীল নামগুলি দীর্ঘ হয়, তাহলে কোডটি আরও কঠিন হয়ে উঠবে:

প্রোগ্রাম কোড
class User {
    ......
    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public List<String> getFriends() {
        return friends;
    }

    public ExtraInformation getExtraInformation() {
        return extraInformation;
    }
}

User user = new User();

System.out.println("User = {name: " + user.getName() + ", age:" + user.getAge() + " years, friend: " + user.getFriends().get(0) + ", weight: " + user.getExtraInformation().getWeight() + " kg.}");

খুব পঠনযোগ্য নয়, তাই না?

কিন্তু বাস্তব-বিশ্বের প্রোগ্রামগুলিতে এটি একটি সাধারণ পরিস্থিতি, তাই আমি আপনাকে এই কোডটি আরও সহজ এবং আরও সংক্ষিপ্তভাবে লেখার একটি উপায় সম্পর্কে বলতে চাই।

String.format

স্ট্রিং ক্লাসের একটি স্ট্যাটিক format()পদ্ধতি রয়েছে: এটি আপনাকে ডেটা সহ একটি স্ট্রিং একত্রিত করার জন্য একটি প্যাটার্ন নির্দিষ্ট করতে দেয়। কমান্ডের সাধারণ চেহারা নিম্নরূপ:

String name = String.format(pattern, parameters);

উদাহরণ:

কোড ফলাফল
String.format("Age=%d, Name=%s", age, name);
Age=12, Name=Amigo
String.format("Width=%d, Height=%d", width, height);
Width=20, Height=10
String.format("Fullname=%s", name);
Fullname=Diego

পদ্ধতির প্রথম প্যারামিটার হল একটি ফরম্যাট স্ট্রিং যাতে আপনার ডেটা সন্নিবেশ করাতে প্রয়োজন এমন জায়গায় ফর্ম্যাট স্পেসিফায়ার (যেমন এবং ) format()নামে বিশেষ অক্ষর সহ সমস্ত পছন্দসই পাঠ্য থাকে।%d%s

পদ্ধতিটি format()এই %sএবং %dফরম্যাট স্পেসিফায়ারগুলিকে প্যারামিটারগুলির সাথে প্রতিস্থাপন করে যা প্যারামিটার তালিকায় ফর্ম্যাট স্ট্রিং অনুসরণ করে। যদি আমরা একটি স্ট্রিং সন্নিবেশ করতে চাই, তাহলে আমরা লিখি %s। যদি আমরা একটি সংখ্যা সন্নিবেশ করতে চাই, তাহলে বিন্যাস নির্দিষ্টকারী হল %d। উদাহরণ:

কোড ফলাফল
String s = String.format("a=%d, b=%d, c=%d", 1, 4, 3);
sসমান"a=1, b=4, c=3"

এখানে বিন্যাস নির্দিষ্টকরণের একটি সংক্ষিপ্ত তালিকা রয়েছে যা বিন্যাস স্ট্রিং এর ভিতরে ব্যবহার করা যেতে পারে:

স্পেসিফায়ার অর্থ
%s
String
%d
interger: byte, short, int,long
%f
প্রকৃত সংখ্যা float:,double
%b
boolean
%c
char
%t
Date
%%
%চরিত্র

এই স্পেসিফায়ারগুলি ডেটার ধরন নির্দেশ করে, তবে এমন কিছু নির্দিষ্টকরণও রয়েছে যা ডেটার ক্রম নির্দেশ করে। এর সংখ্যা দ্বারা একটি যুক্তি পেতে (সংখ্যা একটি থেকে শুরু হয়), আপনাকে " " এর পরিবর্তে " " লিখতে হবে। উদাহরণ:%1$d%d

কোড ফলাফল
String s = String.format("a=%3$d, b=%2$d, c=%d", 11, 12, 13);
sসমান"a=13, b=12, c=11"

%3$d3য় আর্গুমেন্ট পাবেন, %2$dদ্বিতীয় আর্গুমেন্ট পাবেন এবং %dপ্রথম আর্গুমেন্ট পাবেন। এবং %sফর্ম্যাট %dস্পেসিফায়ারগুলি আর্গুমেন্টগুলিকে নির্দেশ করে যেমন নির্দিষ্টকারী নির্বিশেষে %3$dবা%2$s



3. স্ট্রিং পুল

স্ট্রিং লিটারাল হিসাবে কোডে নির্দিষ্ট করা প্রতিটি স্ট্রিং মেমরির একটি এলাকায় সংরক্ষণ করা হয় যাকে StringPoolপ্রোগ্রামটি চলাকালীন বলা হয়। StringPoolস্ট্রিং সংরক্ষণের জন্য একটি বিশেষ অ্যারে। এর উদ্দেশ্য হল স্ট্রিং স্টোরেজ অপ্টিমাইজ করা:

প্রথমত, কোডে উল্লিখিত স্ট্রিংগুলি অবশ্যই কোথাও সংরক্ষণ করতে হবে, তাই না? কোডে কমান্ড থাকে, কিন্তু ডেটা (বিশেষ করে বড় স্ট্রিং) মেমরিতে কোড থেকে আলাদাভাবে সংরক্ষণ করতে হবে। শুধুমাত্র স্ট্রিং অবজেক্টের রেফারেন্স কোডে উপস্থিত হয়।

দ্বিতীয়ত, সমস্ত অভিন্ন স্ট্রিং লিটারেল শুধুমাত্র একবার মেমরিতে সংরক্ষণ করতে হবে। এবং যে ঠিক কিভাবে এটি কাজ করে. যখন আপনার ক্লাস কোড জাভা মেশিন দ্বারা লোড করা হয়, তখন সমস্ত স্ট্রিং লিটারেল যোগ করা হয় StringPoolযদি সেগুলি ইতিমধ্যে সেখানে না থাকে। যদি তারা ইতিমধ্যে সেখানে থাকে, তাহলে আমরা কেবল থেকে একটি স্ট্রিং রেফারেন্স ব্যবহার করি StringPool

তদনুসারে, আপনি যদি আপনার কোডের বেশ কয়েকটি ভেরিয়েবলে একই আক্ষরিক বরাদ্দ করেন String, তবে এই ভেরিয়েবলগুলিতে একই রেফারেন্স থাকবে। একটি আক্ষরিক শুধুমাত্র একবার যোগ করা হবে StringPool. অন্য সব ক্ষেত্রে, কোডটি ইতিমধ্যেই লোড করা স্ট্রিংয়ের একটি রেফারেন্স পাবে StringPool

এটি মোটামুটিভাবে কীভাবে কাজ করে তা এখানে:

কোড স্ট্রিংপুলের সাথে কাজ করা
String a = "Hello";
String b = "Hello";
String c = "Bye";
String[] pool = {"Hello", "Bye"};
a = pool[0];
b = pool[0];
c = pool[1];

এই কারণেই aএবং bভেরিয়েবল একই রেফারেন্স সংরক্ষণ করবে।

intern()পদ্ধতি

এবং সবচেয়ে ভাল অংশ হল যে আপনি প্রোগ্রাম্যাটিকভাবে যেকোনো স্ট্রিং যোগ করতে পারেন StringPool। এটি করার জন্য, আপনাকে কেবল Stringভেরিয়েবলের intern()পদ্ধতিতে কল করতে হবে।

পদ্ধতিটি intern()স্ট্রিংটিকে যুক্ত করবে StringPoolযদি এটি ইতিমধ্যে সেখানে না থাকে এবং স্ট্রিংটিতে একটি রেফারেন্স ফিরিয়ে দেয় StringPool

যদি দুটি অভিন্ন স্ট্রিং পদ্ধতি StringPoolব্যবহার করে যোগ করা হয় intern(), পদ্ধতিটি একই রেফারেন্স প্রদান করে। এটি রেফারেন্স দ্বারা স্ট্রিং তুলনা করতে ব্যবহার করা যেতে পারে। উদাহরণ:

কোড বিঃদ্রঃ
String a = new String("Hello");
String b = new String("Hello");
System.out.println(a == b);


false
String a = new String("Hello");
String b = new String("Hello");

String t1 = a.intern();
String t2 = b.intern();
System.out.println(a == b);
System.out.println(t1 == t2);





false
true

আপনি প্রায়শই এই পদ্ধতিটি ব্যবহার করার সম্ভাবনা কম, তবে লোকেরা সাক্ষাত্কারে এটি সম্পর্কে জিজ্ঞাসা করতে পছন্দ করে । তাই না জানার চেয়ে এ সম্পর্কে জানা ভালো।