# পাঠ ৭: স্ট্রিং  অপারেশান

* স্ট্রিং তেরি করা
* স্ট্রিং লেন্থ এবং স্ট্রিং অপারেশান
* ক্যারেকটার এক্সট্রাকশন
* স্ট্রিং কমপেরিঝন
* স্ট্রিং সার্চিং এবং মডিফাইং
* ডাটা কনভারশন
* স্ট্রিং বাফার
* স্ট্রিং বিউল্ডার
* সারসংক্ষেপ

জাভাতে স্ট্রিং ব্যাপকভাবে ব্যবহৃত একটি অবজেক্ট। স্ট্রিং হচ্ছে কতগুলো ক্যারেক্টার-এর সিকুয়েন্স বা অনুক্রম।\
স্ট্রিং তৈরি করা খুব সহজ। যেমন –

‌

```java
        String greeting = "Hello world!";
```

এখানে "Hello world!" হচ্ছে স্ট্রিং লিটারেল যা অকনেগুলো ক্যারেক্টার উদ্ধৃতি চিহ্নের (“”) মাঝে লিখতে হয়।

জাভা কোডের মধ্যে কোন স্ট্রিং লিটারেল থাকলে কম্পাইলার সেটিকে String অবজেক্ট –এ পরিণত করে যার ভ্যালু হয় উদ্ধৃতি চিহ্নের (“”) মাঝের ক্যারেক্টার গুলো ।

তবে অন্যান্য অবজেক্ট এর মতো String ও new কিওয়ার্ড এবং কন্সট্রাকটর ব্যবহার করে তৈরি করতে পারি। String ক্লাসের ১৩ টি কনস্ট্রাকটর আছে। সুতরাং আমরা আরও ১৩ টি উপায়ে স্ট্রিং তৈরি করতে পারি।

উদাহরণ –

```java
        String str = new String("Hello world!");
        char[] helloArray = { 'h', 'e', 'l', 'l', 'o', '.' };
        String helloString = new String(helloArray);
```

**String Length**

String ক্লাসের মধ্যে length() মেথড থাকে যা একটি স্ট্রিং এর মধ্যে কতগুলো ক্যারেক্টার থাকে তার সংখ্যা রিটার্ণ করে। String loremIpsum ="Lorem ipsum dolor sit amet.";

```java
       int len = loremIpsum.length();
```

**স্ট্রিং Concatenating**

আমরা বেশ কয়েকটি উপায়ে স্ট্রিং কনকেট করতে পারি -

```java
     string1.concat(string2); //  concat()মেথড ব্যবহার করে 
     "My name is ".concat("Rumplestiltskin"); // লিটারেল ব্যবহার করে 
     "Hello," + " world" + "!" //  + অপারেটর ব্যবহার করে
```

স্ট্রিং এর ভেতর বেশ কিছু মেথড আছৈ যেগুলো ব্যবহার করে আমরা স্ট্রিং মেনুপুলেট করতে পারি।

charAt() – এই মেথড ব্যবহার করে আমরা কোন ইনডেক্স এর ক্যারেক্টার আলাদা করতে পারি। উদাহরণ-

```java
    String hello = "Hello";
    char getCharOfIndex2 = hello.charAt(2);
```

substring() – এই মেথড ব্যবহার করে আমরা একটি স্ট্রিং থেকে এর সাব-স্ট্রিং বা কোন নির্দিষ্ট অংশ আলাদা করতে পারি। উদাহরণ-

```java
    String str1 = "Hello world!";
    String hello =str1.substring(0,5);
```

toLowerCase() – লোওয়ারকেস লেটারে কনভার্ট করার জন্যে এই মেথড ব্যবহার করি। toUpperCase() আপারকেস লেটারে কনভার্ট করার জন্যে এই মেথড ব্যবহার করি।

উদাহরণ –

```java
      String hello = "Hello";
      hello.toUpperCase(); // HELLO
      hello.toLowerCase(); // hello
```

নিচে আরও কিছু উদহরণ দেখানো হল-

```java
      String str2 = "Hello world!"; 
      int indexOfHaitch = str2.indexOf("H");
```

### বিশেষভাবে লক্ষণীয়

জাভাতে স্ট্রিং ক্লাস **immutable**, এর মানে হচ্ছে, একবার কোন স্ট্রিং অবজেক্ট তৈরি করলে তাকে আর পরিবর্তন করা যাবে না। আমরা অনেক ক্লাস লিখি, তারপর এর মাঝে বিভিন্ন ভ্যারিয়েবল রাখি, অবজেক্ট তৈরি করার পর সেই অবজেক্টর এর ভেতরের ভ্যারিয়েবল গুলো বিভিন্ন সময় পরিবতর্তন করতে পারি। কিন্তু স্ট্রিং এর ক্ষেত্রে এটি সম্ভব নয়। অর্থাৎ আমরা যদি কোন একটি ভ্যালু দিয়ে একবার একটি স্ট্রিং অবজেক্ট তৈরি করি তাহলে সেটি আর পরিবর্তন করা যাবে না।

কিন্তু আমরা অনেকসময়ই স্ট্রিং কনকেট করি, সেক্ষেত্রে যা হয়, মনে করি-

```java
‌‌‌‌‌‌‌‌‌
    String str = "Hello ";
    str = str + "world";

`
```

এখানে যদিও মনে হচ্ছে আমরা স্ট্রিং এর ভ্যালু পরিবর্তন করে ফেলেছি। কিন্তু আসলে যা হচ্ছে তা হলো, আমরা প্রথমে একটি অবজেক্ট তৈরি করেছি, তারপর সেই অবেজক্টএর ভ্যালু এবং নতুন একটি ভ্যালু নিয়ে নতুন একটি অবজেক্ট তৈরি করেছি, এবং যা str এখন নতন সেই অবজেক্টকে রেফার করছে। আগের অবজেক্টটিকে গার্বেজ কালেক্টর নিয়ে চলে যাবে।

এখন প্রশ্ন হচ্ছে, কেন এই **immutability** দরকার হয়।

স্ট্রিং পুল (**Stirng Pool**) সম্পর্কে হয়তো অনেকেই জানি। এটি একটি জাভা হিপ এর একটি স্পেশাল এরিয়া । আমাদের যদি নতুন একটি স্ট্রিং তৈরি করতে হয়, সেই স্ট্রিং যদি আগে থেকেই স্ট্রিং পুল এ থেকে থাকে, তাহলে নতুন করে আর তৈরি না করে আগের অবজেক্টটির রেফারেন্স দেওয়া হয়। এতে করে আমাদের মেমরি ফ্রুটপ্রিন্ট অনেক কমে যাচ্ছে।

```java
String string1 = "abcd";
String string2 = "abcd";
`
```

আমরা যদি এই দুটি লাইন লিখি, তাহলে আসলে জাভা হিপ এ একটি স্ট্রিং অবজেক্ট-ই থাকবে, দুটি তৈরি হবে না। যদি স্ট্রিং immutable না হয়, তাহলে একটি স্ট্রিং যদি পরিবর্তন করি, তাহলে আসলে অন্যান্য রেফারেন্স গুলোও পরিবর্তন হয়ে যাবে।

এছাড়াও, আমরা জানি যে স্ট্রিং এর **hashcode** খুব বেশি ব্যবহার করা হয়। যেমন **HashMap**। স্ট্রিং **immutable** হওয়ায় এটা গ্যারান্টিড যে, সবসময় **hashcode** এক-ই হবে, সুতরাং আমরা প্রতিবার **hashcode** ক্যালকুলেট না করে নির্ধিদ্বায় ক্যাশিং করতে পারি।

আমরা স্ট্রিং প্যারামিটার হিসেব অনেক বেশি ব্যবহার করে থাকি, যেমন, নেটওয়ার্ক কানেকশান, ফাইল অপেনিং ইত্যাদির ক্ষে্ত্রে। সুতরাং এটি **immutable** না হলে পরিবর্তন করে ফেলা সম্ভব যা কিনা একটি সিরিয়াস রকম সিকিউরিটি থ্রেড হতে পারে। কিন্তু যেহেতু স্ট্রিং **immutable**, সুতরাং সেই সম্ভবনা নেই।

তাছাড়া স্ট্রিং **immutable** হওয়ায় এটি ন্যাচারালি থ্রেড সেইফ, এবং স্বাধীনভাবে যে কেন থ্রেড একসেস করে পারে আমাদেরকে কষ্ট করে এর থ্রেড সেইফটি নিয়ে চিন্তা করতে হয় না।

## চলবে ......
