நவம்பர் 07, 2010

ஜாவா தொடர் - Strings அடிப்படைகள்.

Strings புரோகிராமிங்கில் தவிர்க்க முடியாத ஒன்று.  வார்த்தைகள் இல்லையென்றால் மொழி ஏது?  பல வார்த்தைகள் சேர்ந்து சொற்றொடர் அமைகிறது.  இது புரோகிராமிங் சங்கதிக்கும் பொருந்தும்.  ஒரு மொழியில் உரையாடுவதற்கு வார்த்தைகள் எவ்வளவு அவசியம், அதுபோல strings பயனர் இடைமுகப்பு உருவாக்கப் பணியில் மிக முக்கிய பயன்வகிக்கிறது.  Strings என்பது பயனர் இடைமுகப்பில் மட்டும் வருவதல்ல,  இது பல்வேறு இடங்களில் பயன்படும்.  C மொழி படித்தவரிடம் String என்றால் என்ன என்று கேட்டால், array of characters எழுத்துக்களின் கோர்வை என அழகாக பதில் சொல்லிவிடுவார். 

Integer, float, boolean, character இவையெல்லாம் data typeகள் என அழைக்கப்படுகிறது.  எடுத்துக்காட்டிற்கு a, b என இரண்டு variableகள் இருக்கிறதென்று வைத்துக்கொள்வோம்.  இவை  என்ன data type என தெரிந்தால்தான் இவற்றில் என்னென்ன செய்ய முடியும், எவை முடியாது எனக் கூற முடியும்.  Data typeகள் புரொகிராமிங்கின் அரிச்சுவடி ஆகும்.  இதை புரிந்து கொள்வதில் சிக்கல் இருப்பதால்தான் புரோகிராமிங் என்பது சிலருக்கு எட்டாக் கனியாகவும், பலருக்கு கசப்பான அனுபவமாகவும் இருக்கிறது.

சரி ஜாவாவில் stringகளை எவ்வாறு பயன்படுத்துதெனப் பார்ப்போம்.  சி, சி++ போல ஜாவாவிலும் string என்றொரு data type கிடையாது.  Stringகை சுக்கு நூறாய் உடைத்தால், கிடைப்பது எழுத்துக்களாக characters இருக்கும்.  ஜாவாவிலும் Character என ஒரு data type உள்ளது.  மிக முக்கியமாய் ஜாவாவில் அறிந்து கொள்ள வேண்டியது என்னவென்றால் இங்கு strings objectகளாகக் கையாளப் படுகிறது.  ஆப்ஜெக்ட் என்று ஒன்று இருந்தால், அதற்கு வடிவம் கொடுக்க class ஒன்று இருக்கும்.   Classஐ இடியாப்ப உரலாகவோ, முறுக்கு உரலாகவோ கற்பனை செய்து கொள்ளுங்கள்.  நமக்கு தேவையான பொருள்  இப்படித்தான் வரவேண்டும் என ஒரு கருவியை வடிவமைத்து வைத்திருக்கிறோம்.  அதை வைத்துக் கொண்டு வேண்டிய அளவு இடியாப்பத்தையோ, முறுக்கையோ புழிந்து கொள்கிறோம்.  இதையேத்தான் classகளும் செய்கிறன.  ஒரு ஆப்ஜெக்ட் எப்படி இருக்க வேண்டும் எனும் வரையறைகளை அதன் class சொல்கிறது.  அந்த class மூலமாக அதன் வகையறாக்களான எத்தனை ஆப்ஜெக்டுகளை வேண்டுமானாலும் உருவாக்கிக் கொள்ளலாம்.

ஜாவாவில் string என்பது ஆப்ஜெக்டுகள் எனத் தெரிந்து கொண்டோம்.    சரி, ஜாவாவில் stringகளை எவ்வாறு உருவாக்குவது?  இதென்ன கேள்வி, stringக்கான classஐக் கொண்டுதான்.  பின்னர் string ஆப்ஜெக்டை உருவாக்க string class இல்லாமலா?

இந்த classஐ எப்படி எழுதுவது?  அட சரியா போச்சு போங்க, நாம எழுதுனா நம்ம கதை கிழிஞ்சிடாதா!  அந்த சிரமத்த நமக்கு கொடுக்கக் கூடாதுன்னுதான் ஜாவாவ உருவாக்குன மகராசன்களே string ஆப்ஜெக்டுகளை உருவாக்கிக் கொள்வதற்கு String.classஐயும் தந்துவிட்டு போயிருக்காங்க. 

Classகளை ஒழுங்கா அடுக்கி வைக்க packages பயன்படுகிறது.  Packageகளை Implicit packages, explicit packages என இருவகையில் குறிப்பிடலாம்.  Implicit packages என்பது தன்னியல்பாக default வருவது, explicit packages நாமாகவே உருவாக்கிக் கொள்வது.  String என்பது ஜாவாவுடன் தன்னியில்பாகவே வரும் class எனப் பார்த்தோம்.  அது java.lang எனும் packageல் இருக்கிறது.  ஒரு classஐ பயன்படுத்த முதலில் அதை import இறக்குமதி செய்ய வேண்டும். 

java.lang.String name;

import java.lang.*;
String name;
என எழுதுவதற்கு பதில் நேரடியாக String name; என்று எழுதிக் கொள்ளலாம்.  java.lang packageஐ நாம் import செய்யத் தேவையில்லை,  JVMமே அந்த வேலையைப் பார்த்துக் கொள்ளும்.

String name;
name என்றொரு variableஐ உருவாக்குகிறோம், அல்லது ஒரு stringகிற்கு name என்றொரு object referenceஐ (string object) உருவாக்குகிறோம் என்றும் சொல்லலாம்.  Object oriented programmingல் ஒரு ஆப்ஜெக்டுக்கு variable உருவாக்குகிறோம் எனச் சொல்வதைவிட ஒரு ஆப்ஜெட்டுக்கு reference உருவாக்குகிறோம் எனச் சொல்வது மிகப் பொருத்தமாக இருக்கும். 

ஒரு string ஆப்ஜெட்டுக்கு reference உருவாக்கி விட்டோம்.  இதனைப் பயன்படுத்த ஒரு ஆப்ஜெக்டை உருவாக்கி அதன் referenceஐ (மெமரியில் அதன் addressஐக் குறிப்பது) object reference variableல் சுட்ட வேண்டும்.

name = new String("Hello");
name = "Hello";
இதில் எந்த முறையில் வேண்டுமானாலும் நமக்குத் தேவையான stringகளை உருவாக்கிக் கொள்ள முடியும்.  இந்த இரண்டு வழிகள் மட்டுமல்ல,Stringகளை பல வழிகளில் ஜாவாவில் உருவாக்க முடியும்.  String classல் உள்ள overloaded constructors இதனை சாத்தியமாக்குகின்றது.  Constructors குறித்து அடுத்தடுத்த பதிவுகளில் நிதானமாக பார்ப்போம்.

பொதுவாக ஒரு ஆப்ஜெக்டை உருவாக்க 'new' keyword பயன்படுகிறது.  Stringகளை உருவாக்க new குறிச்சொல்லை பயன்படுத்தாமலே, சுருக்கு வழியில் உருவாக்கலாம்.  அந்த சுருக்கு வழி, இரட்டை மேற்கோற் குறிக்குள் எழுதுவது (inside double quotes).  இப்படி சுருக்கு வழியில் stringகளை உருவாக்கும் விதத்தை literal notation எனக் குறிப்போம்.

'a' இப்படி எழுதுவதற்கும், "a" என எழுதுவதற்கும் நிறைய வேறுபாடு இருக்கிறது.  முதலாவது 'a' ஆங்கில எழுத்துக்களில் உள்ள முதல் எழுத்தைக் (character) குறிக்கிறது.  இரண்டாவது, "a" எனும் stringஐக் குறிக்கிறது.  ஜாவாவில் stringகுகள் objectட்டாகக் கையாளப் படுவதால் நமக்கு பல வசதிகள் உள்ளது.  பொதுவாக இதில் நாம் செய்ய நினைக்கும் அத்தனை செயல்களுக்கும், அதை செய்வதற்கு 
உதவியாய் பல்வேறு methodடுகள் நமக்கு வரப்பிரசாதமாய்க் கிடைத்துள்ளன.

Eclipseல் ஒரு stringகையோ, அதனை சுட்டும் referenceஐயோ பயன்படுத்துகையில், ஒரு புள்ளி (period) வைத்ததுமே அதில் என்னென்ன methodகள், என்னென்ன properties இருக்கிறதென்று பட்டியல்லிட்டுவிடும்.  எதையுமே நாம் மனப்பாடம் செய்ய வேண்டியதில்லை.  அந்தந்த methodகளின் பெயரைப் படித்தாலே ஓரளவுக்கு யூகித்து விடலாம்.

Stringல் குறிப்பாக அடிக்கடி பயன்படுத்தும் methodகளை பார்த்து விடுவோம்.
length() என்பது stringகில் ஒரு முக்கியமான method ஆகும்.  "Rajkumar" எனும் stringல் எத்தனை எழுத்துக்கள் இருக்கிறதென்று அறிய "Rajkumar".length() எனக் கொடுத்தால் போதும்.  இங்கு stringஐ நாம் நேரடியாகக் கொடுப்பதால், புரோகிராமை இயக்குவதற்கு முன்பே 8 எழுத்துக்கள் என விடையைச் சொல்லி விடலாம்.  என்ன string வருமென்றே தெரியாது என வைத்துக் கொள்வோம், அந்த இடத்தில் stringதனை சுட்டும் string referenceஐ பயன்படுத்திக் கொள்ளலாம்.
எடு:    String name;
         name = "Rajkumar";
இப்போது நீங்கள் name.length() எனக் கொடுத்தாலும் சரியான விடை வரும்.

அடுத்து வெவ்வேறு stringகளை ஒன்றாய் இணைப்பது (concatenation) எவ்வாறு எனப் பார்ப்போம்.  இதற்கு concat() method பயன்படுகிறது.
    string1.concat(string2);
    "Raj".concat("kumar") --------------> "Rajkumar"
new குறிச்சொல் பயன்படுத்தாமலேயே " " மேற்கோள் குறிகளைக் கொண்டு சுருக்கு வழியில் எவ்வாறு stringகளை உருவாக்குவது எனப் பார்த்தோம்.  அதுபோல concat() methodஐ பயன்படுத்தாமலேயே + கூட்டல் குறியைக் கொண்டும் வெவ்வேறு stringகளை இணைத்துக் கொள்ளலாம்.

"tamil".concat("cpu") என எழுதுவதற்கு பதிலாக "tamil" + "cpu" என எழுதிக் கொள்ளலாம்.  இவை இரண்டும் ஒரே வெளியீட்டைத்தான் தரும்.

ஜாவாவில் console (console என்றால் திரை. நமது கணினியில் கட்டளைகளை இயக்கும் command prompt/terminal என வைத்துக் கொள்ளுங்கள்) புரோகிராமில் நாம் சொல்ல நினைக்கும் வரிகளை System.out.printlnல் எழுதுவோம்.  அதைக் கொண்டு சில எடுத்துக்காட்டுகளைக் காண்போம்.

String name = "Rajkumar";
System.out.println("name"); என எழுதினால் "name" என்பதுதான் வெளியீடாகக் (output) கிடைக்கும்.  இரட்டை மேற்கோள் குறியில் எதை எழுதினாலும் அது string என அர்த்தம் கொள்ளப் படும்.  System.out.println(name) என்பது நமக்கு வேண்டிய வெளியீட்டைத் தரும்.

String firstName = "Rajkumar";
String lastName = "Ravi";
String fullName = firstName + lastName;

System.out.println(fullName);
System.out.println(firstName + lastName);

இரண்டும் ஒரே வெளியீட்டைத்தான் தரும்.  RajkumarRavi என எழுதுவதற்கு இரண்டு பெயர்களுக்கும் ஒரு இடைவெளி விட்டு Rajkumar   Ravi என எழுதினால் நன்றாக இருக்குமல்லவா.  இந்த இரண்டு பெயர்களுக்கும் இடையே "  " இப்படி சொருகி விடுங்கள்.

System.out.println(firstName + "  " + lastName);
System.out.println("Normal:  " + firstName);
System.out.println("Capital letters:  " + firstName.toUpperCase() ); இதற்கு விளக்கம் தேவையில்லையென நினைக்கிறேன்.

ஜாவாவில் stringஸ்களை கையாளும்போது நாம் அடிக்கடி செய்யும் தவறு, இரண்டு stringகளை == operator மூலம் ஒன்றாக உள்ளனவா எனப் (compare) பார்ப்பது.

String name1 = "Raghu";
String name2 = "Raghu123".subString(0,5);



if ( name1 == name2)
    System.out.println("name1 and name2 are equal");
else
    System.out.println("name1 and name2 are different");

இதற்கு விடையை நாம் யூகித்தால் name1 and name2 are equal என வருமென அடித்துச் சொல்வோம்.  ஆனால் அதுதான் இல்லை.  இரண்டும் ஒன்றில்லையா, ஆம் இரண்டும் ஒன்றில்லை name1றும் name2வும் வெவ்வேறு "Raghu" எனும் stringகளைக் குறிக்கிறது.

சரி இப்படி எடுத்துக் கொள்ளுங்கள்.
int a = 5;
int b = 5;
if (a == b)
   System.out.println("a is equal to b.");
else
   System.out.println("No, first 5 is different from second 5");

இதற்கு விடை a is equal to b என வரும்.  பொதுவாக ஜாவாவில் எல்லாமே ஆப்ஜெக்டுகளாகத்தான் கையாளப் படுகிறது, data typeற்கு மட்டும் இது விதிவிலக்கானது.  வேகமான இயக்கத்திற்காக அடிப்படை data typeகள் C மொழியில் உள்ளது போலவே நேரடியாகக் கையாளப்படுகிது.  ஆனால் stringகுகள் data type பிரிவில் வராது என்பதை மீண்டும் நினைவில் நிறுத்திக் கொள்க.

நீங்கள் உருவாக்கும் ஒவ்வொரு stringகும் தனித்தனி string ஆப்ஜெக்ட்டுகளாகும்.  ஆப்ஜெக்டுகளை compare செய்ய equals() method பயன்படுகிறது.  இது அனைத்து ஆப்ஜெக்டுகளுக்கும் பொருந்தும்.  ஜாவா தெரியும் என நம் சுயவிவரக் குறிப்பில் (resume) நாம் எழுதியிருந்தால் நம்மிடம் முதலில் வைக்கப் படும் கேள்வி what is the root class of java?  ஜாவாவின் ஆணிவேரான மூல class எது என்பதாக இருக்கும்.  ஜாவாவில் எல்லாமே ஆப்ஜெக்ட்டுகள் என்றால் அந்த class Object.classஆக இல்லாமல் வேறெந்த classஆக இருக்கும்.  Object classல் இருக்கும் அனைத்து public methodகளையும் எந்தவொரு ஆப்ஜெக்ட்டாக இருந்தாலும் அதில் பயன்படுத்திக் கொள்ளலாம்.  இதுதான் inheritanceன் மகிமை.

சாதாரணமாக class MyClass { .. என்று எழுதுவோம். 
ஒரு classஐ inherit செய்ய class MyClass extends AnotherClass {... என எழுதுவோம்.  இப்போது AnotherClassல் இருக்கும் அனைத்து public methodகளையும் MyClassல் பயன்படுத்திக் கொள்ளலாம்.

AnotherClassல் இருக்கும் methodகளுக்கு நாம் எழுதும் MyClassல் புது விளக்கம் கொடுத்தால் அதுதான் overriding.  ஜாவாவில் உள்ள அனைத்து ஆப்ஜெக்ட்டுகளும் தன்னியல்பாகவே Object classசினை extend செய்திருப்பதால், Object classல் உள்ள மெத்தட்களை அப்படியேவும் பயன்படுத்தலாம் overridingகும் செய்து கொள்ளலாம்.  Object classல் ஏகப்பட்ட methodகள் இருந்தாலும் நான் பயன்படுத்திப் பார்த்தது toString() மற்றும் equals().

சரி ஒரு வழியாக stringகிற்கு திரும்புவோம்.  ஜாவாவில் strings ஆப்ஜெக்ட் என்பதால் Object classன் அங்கமான equals(), toString() methodகளை இயல்பாகவே பயன்படுத்திக் கொள்ளலாம்.  இரண்டு stringகள் ஒன்றாக இருக்கின்றனவா என சோதிக்க == ஆபரேட்டருக்கு பதிலாக equals() மெத்தடை பயன்படுத்தவும்.

if ( name1.equals(name2)).... எனக் கொடுக்க வேண்டும்.   பிறகு == ஆப்பரேட்டரை பயன்படுத்தும் போது ஏன் பிழை காட்டவில்லை.  equals() மெத்தட் ஆப்ஜெட்டுகளின் உள்ளடக்கம் (contents) ஒன்றாக இருக்கின்றனவா என பரிசோதிக்க.  == ஆபரேட்டர் இரண்டும் ஒரே ஆப்ஜெக்ட்டைத்தான் குறிக்கின்றனவா (same reference) என சோதிக்க.

String name1 = "Raj"
String name2 = name1; // name1ன் reference name2விற்கும் காப்பி செய்யப் படுகிறது.
if (name1 == name2)------> என்றால் சரிதான் என விடை வரும்.

ஜாவா புத்தகத்தில் படித்திருக்கிறீர்களா (திறந்தாவது பார்த்ததுண்டா, என்ன இல்லையா! அட நம்ம ஜாதிதான்.. :) Strings are immutable என்றொரு வாக்கியம் இருக்கும்.  இல்லையென்றால் நீங்கள் படிப்பது ஜாவா புத்தகம்தானா என்பதை உறுதி செய்து கொள்ளவும்.  இதில் என்ன சொல்ல வருகிறார்கள்.  ஆங்கிலத்தில் mutable என்றால் மாற்றக் கூடியது, மாறும் தன்மை கொண்டது எனப் பொருள்.  Immutable என்பது mutableக்கு எதிர்ப் பதம்.

அதாவது ஜாவாவில் ஒரு stringகை உருவாக்கிய பின்னர் அதில் மாற்றம் செய்ய முடியாது.
இதென்ன புதுக்கதை?

String name = "Raghu"; 
name = "Raj";  "Raghu" எனும் stringகைத்தான் "Raj" எனும் stringகால் overlap செய்து விட்டோமே, பிறகு stringசை immutable எனச் சொல்வது நியாயம்தானா? இல்லை இல்லை "Raj" என்ற புது stringகை உருவாக்குகிறோமே தவிர "Raghu" என்ற stringகை திருத்தி எழுதவில்லை.  name என்பது string ஆப்ஜெக்ட் அல்ல, அது உண்மையான stringகளைக் குறிக்கும் வெறும் referenceதான்.  Referenceகளை மாற்ற முடியுமே தவிர, stringகுகளையல்ல.  தேவையில்லாமல் ஆயிரக்கணகான stringகள் இருந்தால் சிஸ்டமே ஸ்தம்பித்து விடும் என்பதை நினைவில் கொள்க.  மாறும் வகைகொண்ட stringகளை உருவாக்க StringBuffer class பயன்படுகிறது.  அதைக்குறித்து எழுதி பழிபாவங்களுக்கு ஆளாக விரும்பவில்லை, மேலதிக விவரம் வேண்டுவோர் புத்தகத்தில் படித்து தெரிந்து கொள்ளவும்.

இக்கட்டுரையில் தேவையில்லாக் கதைகள் நிறைய இருக்கின்றது எனக் கருதினால் மன்னிக்கவும், இது ஜாவா ஓரளவுக்கு தெரிந்தவர்களுக்கான தொடரல்ல என்பதை தாழ்மையுடன் தெரிவித்துக் கொள்கிறேன்.  புரோகிராம் எழுதுவதை மலையை பெயர்க்கும் வேலையாக நினைக்கும்
அப்பாவிகளுக்காக எனக்கு புரிந்த வரையில் பகிர்ந்து கொள்கிறேன்.  ஜாவா கற்பது கடினமானது, ஆனால் கற்றே தீர வேண்டும் என நினைப்பவர்களுக்கு இத்தொடரினை அறிமுகப் படுத்துங்கள்.  எனக்கும் மனநிறைவு கிட்டும். நன்றி.
charAt(), subString(), trim()... போன்றவற்றை நீங்களாகவே படித்து பயன்படுத்திப் பாருங்கள்.

சுருக்கமாக நச்சென்று ஜாவா strings பற்றி சொல்ல வேண்டுமானால்
java strings are objects   &
java strings are immutable.

                                                                              -- தொடரும்.