String Handling
String is immutable — when you do s = s + "x", a new String object is created; the old one stays as it was.
If you need lots of changes (like in a loop), use StringBuilder instead — it modifies the same object, and is fast.
String s = "Hi";
s = s + " Java"; // new object created
StringBuilder sb = new StringBuilder("Hi");
sb.append(" Java"); // same object modifiedJab tum String s = "Hi"; likhte ho (literal), Java pehle "String Pool" (ek special memory area, Heap ke andar hi) mein check karta hai ki "Hi" already exist karta hai kya — agar haan, wahi reference de deta hai (naya object nahi banta, memory bachti hai). Ye sirf tabhi possible hai kyunki String immutable hai — agar koi ek reference se String change kar de, sab shared references corrupt ho jaate.
Lekin new String("Hi") *hamesha* ek naya object Heap mein banata hai, Pool ke bahar — chahe "Hi" pool mein already ho. Isliye new String() se banaye Strings == se compare karna hamesha risky hai.
intern() method call karke tum kisi bhi String ko manually Pool mein daal sakte ho (ya agar already hai to uska pool reference le sakte ho) — rarely use hota hai, lekin memory-sensitive applications mein useful ho sakta hai.
String a = "Hi";
String b = "Hi";
String c = new String("Hi");
System.out.println(a == b); // true (Pool se same object)
System.out.println(a == c); // false (c alag object hai)
System.out.println(a.equals(c)); // true (content same hai)length() String ki lambai deta hai. charAt(i) specific position ka character. substring(start, end) ek hissa nikalता hai (end index exclude hota hai). indexOf("x") pehli baar "x" kaha milta hai (nahi milne par -1).
contains("x") check karta hai substring hai ya nahi. replace("a","b") sab occurrences badal deta hai. trim() (ya modern strip()) leading/trailing spaces hataye. split(",") ek array deta hai, delimiter ke hisaab se tode hue.
toUpperCase()/toLowerCase() case badalte hain. equalsIgnoreCase() case-insensitive comparison. Sab methods NAYA String return karte hain (immutability ki wajah se), original kabhi change nahi hota.
| Method | Kya Karta Hai | Example |
|---|---|---|
| length() | Lambai | "Java".length() → 4 |
| charAt(i) | i-th character | "Java".charAt(1) → 'a' |
| substring(a,b) | Hissa nikalna | "Java".substring(1,3) → "av" |
| indexOf(x) | Position dhoondhna | "Java".indexOf('v') → 2 |
| trim() | Spaces hatana | " Hi ".trim() → "Hi" |
| split(x) | Array mein todna | "a,b".split(",") → ["a","b"] |
| replace(a,b) | Replace karna | "Hi".replace('H','B') → "Bi" |
String s = " Hello Java ";
System.out.println(s.trim()); // "Hello Java"
System.out.println(s.trim().split(" ")[1]); // "Java"Dono mutable hain (same object modify hota hai, String ki tarah baar-baar naya object nahi banta) — append(), insert(), delete(), reverse() jaisi methods dete hain jo object ko in-place modify karti hain.
Fark: StringBuffer thread-safe hai (methods synchronized hain, multiple threads ek saath safely use kar sakte hain) lekin isliye thoda slow (synchronization ka overhead). StringBuilder thread-safe NAHI hai lekin fast hai — single-threaded code mein (jo zyada common hai) StringBuilder hi recommended hai.
Loop mein bahut saari String concatenation karni ho, to StringBuilder use karo — s = s + "x" loop mein karne se har baar ek naya String object banta hai (O(n²) time complexity poore loop ke liye), jabki StringBuilder.append() same object ko modify karta hai (O(n) total).
| String | StringBuilder | StringBuffer | |
|---|---|---|---|
| Mutable? | Nahi | Haan | Haan |
| Thread-safe? | Haan (immutable hai isliye) | Nahi | Haan |
| Speed | Slow (concatenation mein) | Fast | Medium |
| Kab use karein | Fixed text, thread-safety chahiye | Single-thread, loops mein building | Multi-thread String building |
String.format("Name: %s, Age: %d", name, age) se placeholders ke saath clean strings bana sakte ho — %s String ke liye, %d integer, %f decimal (%.2f do decimal places ke saath). System.out.printf() same syntax use karta hai directly print karne ke liye (format() ki tarah, bas return nahi karta, seedha print kar deta hai).
String msg = String.format("%s scored %.1f%%", "Aarav", 92.567);
// "Aarav scored 92.6%"
System.out.printf("Total: %d items%n", 5);String ko immutable/final banaya gaya hai teen wajah se: (1) Security — jaise file paths, network URLs, database credentials String mein pass hote hain; agar mutable hote to koi bhi function beech mein secretly badal sakta tha jisse security holes ban sakte the.
(2) String Pool sirf immutability ki wajah se safely kaam kar sakta hai — agar ek reference change kar de, sab shared references (jo same pooled object point kar rahe hain) corrupt ho jaate.
(3) Thread-safety free milti hai bina extra effort ke — immutable objects multiple threads ke beech safely share ho sakte hain, kyunki koi bhi thread ise change hi nahi kar sakta. Ye String ko HashMap keys ke liye bhi perfect banata hai (hashCode kabhi change nahi hota, cache kiya ja sakta hai — String apna hashCode internally cache bhi karta hai performance ke liye).