String Handling
String immutable है — जब तुम s = s + "x" करते हो, एक नया String object बनता है, पुराना वही रहता है।
अगर बहुत सारे changes करने हैं (जैसे loop में), तो StringBuilder use करो — वो same object को modify करता है, fast होता है।
String s = "Hi";
s = s + " Java"; // new object created
StringBuilder sb = new StringBuilder("Hi");
sb.append(" Java"); // same object modified- String immutable है
- Change पर नया object बनता है
- StringBuilder mutable और fast होता है
जब तुम String s = "Hi"; लिखते हो (literal), Java पहले "String Pool" (एक special memory area, Heap के अंदर ही) में check करता है कि "Hi" already exist करता है क्या — अगर हाँ, वही reference दे देता है (नया object नहीं बनता, memory बचती है)। यह सिर्फ तभी possible है क्योंकि String immutable है — अगर कोई एक reference से String change कर दे, सब shared references corrupt हो जाते।
लेकिन new String("Hi") *हमेशा* एक नया object Heap में बनाता है, Pool के बाहर — चाहे "Hi" pool में already हो। इसलिए new String() से बनाए Strings को == से compare करना हमेशा risky है।
intern() method call करके तुम किसी भी String को manually Pool में डाल सकते हो (या अगर already है तो उसका pool reference ले सकते हो) — rarely use होता है, लेकिन memory-sensitive applications में useful हो सकता है।
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 की लंबाई देता है। charAt(i) specific position का character। substring(start, end) एक हिस्सा निकालता है (end index exclude होता है)। indexOf("x") पहली बार "x" कहाँ मिलता है (नहीं मिलने पर -1)।
contains("x") check करता है substring है या नहीं। replace("a","b") सब occurrences बदल देता है। trim() (या modern strip()) leading/trailing spaces हटाए। split(",") एक array देता है, delimiter के हिसाब से तोड़े हुए।
toUpperCase()/toLowerCase() case बदलते हैं। equalsIgnoreCase() case-insensitive comparison। सब methods नया String return करते हैं (immutability की वजह से), original कभी change नहीं होता।
| Method | क्या करता है | Example |
|---|---|---|
| length() | लंबाई | "Java".length() → 4 |
| charAt(i) | i-th character | "Java".charAt(1) → 'a' |
| substring(a,b) | हिस्सा निकालना | "Java".substring(1,3) → "av" |
| indexOf(x) | Position ढूंढना | "Java".indexOf('v') → 2 |
| trim() | Spaces हटाना | " Hi ".trim() → "Hi" |
| split(x) | Array में तोड़ना | "a,b".split(",") → ["a","b"] |
| replace(a,b) | Replace करना | "Hi".replace('H','B') → "Bi" |
String s = " Hello Java ";
System.out.println(s.trim()); // "Hello Java"
System.out.println(s.trim().split(" ")[1]); // "Java"दोनों mutable हैं (same object modify होता है, String की तरह बार-बार नया object नहीं बनता) — append(), insert(), delete(), reverse() जैसी methods देते हैं जो object को in-place modify करती हैं।
फर्क: StringBuffer thread-safe है (methods synchronized हैं, multiple threads एक साथ safely use कर सकते हैं) लेकिन इसलिए थोड़ा slow (synchronization का overhead)। StringBuilder thread-safe नहीं है लेकिन fast है — single-threaded code में (जो ज़्यादा common है) StringBuilder ही recommended है।
Loop में बहुत सारी String concatenation करनी हो, तो StringBuilder use करो — s = s + "x" loop में करने से हर बार एक नया String object बनता है (O(n²) time complexity पूरे loop के लिए), जबकि StringBuilder.append() same object को modify करता है (O(n) total)।
| String | StringBuilder | StringBuffer | |
|---|---|---|---|
| Mutable? | नहीं | हाँ | हाँ |
| Thread-safe? | हाँ (immutable है इसलिए) | नहीं | हाँ |
| Speed | Slow (concatenation में) | Fast | Medium |
| कब use करें | Fixed text, thread-safety चाहिए | Single-thread, loops में building | Multi-thread String building |
String.format("Name: %s, Age: %d", name, age) से placeholders के साथ clean strings बना सकते हो — %s String के लिए, %d integer, %f decimal (%.2f दो decimal places के साथ)। System.out.printf() same syntax use करता है directly print करने के लिए (format() की तरह, बस return नहीं करता, सीधा print कर देता है)।
String msg = String.format("%s scored %.1f%%", "Aarav", 92.567);
// "Aarav scored 92.6%"
System.out.printf("Total: %d items%n", 5);String को immutable/final बनाया गया है तीन वजह से: (1) Security — जैसे file paths, network URLs, database credentials String में pass होते हैं; अगर mutable होते तो कोई भी function बीच में secretly बदल सकता था जिससे security holes बन सकते थे।
(2) String Pool सिर्फ immutability की वजह से safely काम कर सकता है — अगर एक reference change कर दे, सब shared references (जो same pooled object point कर रहे हैं) corrupt हो जाते।
(3) Thread-safety free मिलती है बिना extra effort के — immutable objects multiple threads के बीच safely share हो सकते हैं, क्योंकि कोई भी thread इसे change ही नहीं कर सकता। यह String को HashMap keys के लिए भी perfect बनाता है (hashCode कभी change नहीं होता, cache किया जा सकता है — String अपना hashCode internally cache भी करता है performance के लिए)।