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()भी हैं।hasNextLine()

आप 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
इंटरजर: 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$dतीसरा तर्क मिलेगा, %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

संभावना नहीं है कि आप अक्सर इस पद्धति का उपयोग करेंगे, लेकिन लोग साक्षात्कारों में इसके बारे में पूछना पसंद करते हैं । इसलिए इसके बारे में जानना न जानने से बेहतर है।