.## 1. හැඳින්වීම
- 1 2. ජාවාහි 문자열 මූලික කරුණු
- 2 3. 문자열 සසඳීමේ ක්රම
- 3 4. ප්රායෝගික උදාහරණ
- 4 5. Performance සහ Optimization
- 5 6. Frequently Asked Questions (FAQ)
- 5.1 Q1. == සහ equals() අතර වෙනස කුමක්ද?
- 5.2 ප්රශ්න 2. equals() භාවිතා කිරීම සමහර විට null නිසා දෝෂ ඇති කරන්නේ ඇයි?
- 5.3 ප්රශ්න 3. මූලික අකුරු සලකා නොබලා string සංසන්දනය කරන්නේ කෙසේද?
- 5.4 ප්රශ්න 4. string වර්ගීකරණ (lexicographical) අනුපිළිවෙලින් සංසන්දනය කරන්නේ කෙසේද?
- 5.5 ප්රශ්න 5. string සංසන්දනය සඳහා හොඳම පුරුදු මොනවාද?
- 6 7. නිගමනය
ජාවාහි 문자열 සසඳීම ඇයි වැදගත්?
ජාවා වැඩසටහන් ලියන විට, 문자열 (String) සමඟ වැඩ කිරීම ඉතා සාමාන්යයයි. පරිශීලක නාම පරීක්ෂා කිරීම, පෝරම ඇතුළත් කිරීම් වල සත්යාපනය, සහ API ප්රතිචාර පරීක්ෂා කිරීම යන උදාහරණ කිහිපයක් පමණක් 문자열 සසඳීම අවශ්ය වන අවස්ථා වේ.
මෙම අවස්ථාවේ, 字符串 (string) නිවැරදිව සසඳන්නේ කෙසේද යන ප්රශ්නය ආරම්භකයන්ට අසාමාන්ය ලෙස පොදු ගැටළුවක් වේ. විශේෂයෙන්, == මෙහෙයුම්කරු සහ equals() ක්රමය අතර වෙනස නොදැනීම අනපේක්ෂිත ප්රතිඵල ලබාදෙන දෝෂ වෙත හේතු විය හැක.
“==” සහ “equals()” අතර වෙනස නොදැනීමේ අවදානම
උදාහරණයක් ලෙස, පහත කේතය බලන්න.
String a = "apple";
String b = new String("apple");
System.out.println(a == b); // Result: false
System.out.println(a.equals(b)); // Result: true
බොහෝ ජනතාව මෙම ප්රතිඵලය ගැන අහම්බෙන් අමුතුයි. 字符串 එකම පෙනුමක් තිබුණද, == වැරදි (false) ලබා දේ, equals() සත්ය (true) ලබා දේ. මෙය සිදුවන්නේ ජාවා 문자열들을 යොමු වර්ගයක් ලෙස සලකන නිසා, == යොමු ලිපිනයන් (reference addresses) සසඳයි, අන්තර්ගතය නොව.
ඔබට දැකගත හැකි පරිදි, 문자열 නිවැරදිව සසඳීම වැඩසටහනේ විශ්වාසනීයත්වය සහ කියවීමට පහසුවට සෘජු බලපෑමක් ඇත. එයට විරුද්ධව, නිවැරදි ක්රමය ඔබට අවබෝධ වූ පසු, බොහෝ දෝෂයන් සිදුවීමට පෙර වැළැක්විය හැක.
ඔබ මෙම ලිපියෙන් ඉගෙන ගන්නා දේ
මෙම ලිපියේ, අපි ජාවාහි 문자열 සසඳීම මූලික කරුණු සිට උසස් තාක්ෂණයන් දක්වා සවිස්තරාත්මකව පැහැදිලි කරමු. සාමාන්ය ප්රශ්නවලට පැහැදිලි හා සංවිධානයකින් යුත් පිළිතුරු ලබා දී, ආරම්භකයන්ට අනුගමනය කිරීම පහසු කරමු.
==සහequals()අතර වෙනස කුමක්ද?- අකුරු කේස් නොසලකා 문자열 සසඳන්නේ කෙසේද?
- ලෙක්සිකෝග්රැෆිකල් (ශබ්දකෝෂ) ක්රමයෙන් 문자열 සසඳන්නේ කෙසේද?
nullසමඟ 문자열 ආරක්ෂිතව සසඳන්නේ කෙසේද?
ප්රායෝගික කේත උදාහරණ හරහා, ඔබට ජාවාහි නිවැරදි 문자열 සසඳීම පිළිබඳ පදනම් තේරුමක් ගොඩනැගීමට හැකි වේ.
2. ජාවාහි 문자열 මූලික කරුණු
문자열 යනු යොමු වර්ගයකි
ජාවාහි, String වර්ගය මූලික වර්ගයක් (උදාහරණයක් ලෙස int හෝ boolean) නොව, යොමු වර්ගයක් වේ. එයින් අදහස් කරන්නේ String විචල්යය ඇත්තේ පණිවිඩයම නොව, heap memory තුළ පිහිටි 문자열 වස්තුවකට යොමු කිරීම ය.
උදාහරණයක් ලෙස, ඔබ පහත ලියන විට:
String a = "hello";
String b = "hello";
a සහ b දෙකම එකම 문자열 වස්තුව "hello" වෙත යොමු විය හැක, එබැවින් a == b සත්ය (true) ලබා දිය හැක. එහෙත්, මෙම හැසිරීම ජාවාගේ 字符串 ලිටරල් (string literal) ප්රතිඵලකරණ යන්ත්රණය (String Interning) මත පදනම් වේ.
문자열 ලිටරල් සහ new String() අතර වෙනස
ජාවාහි, එකම 문자열 ලිටරල් බහු වතාවක් භාවිතා කරන විට, JVM එකම යොමුය නැවත භාවිතා කිරීමෙන් මතක භාවිතය ප්රතිඵලකරණය කරයි. මෙය 문자열 වස්තු බෙදා ගැනීමෙන් මතක කාර්යක්ෂමතාව වැඩි කිරීම සඳහා කරනු ලැබේ.
String s1 = "apple";
String s2 = "apple";
System.out.println(s1 == s2); // true (same literal, same reference)
එකට විරුද්ධව, new යතුර භාවිතා කර 문자열 නිර්මාණය කරන විට, වෙනත් යොමුයක් සමඟ නව වස්තුවක් නිර්මාණය වේ.
String s3 = new String("apple");
System.out.println(s1 == s3); // false (different references)
System.out.println(s1.equals(s3)); // true (same content)
මෙය වෙනස පැහැදිලිව පෙන්වයි: == යොමු සමානත්වය පරීක්ෂා කරයි, equals() අන්තර්ගත සමානත්වය පරීක්ෂා කරයි. ඒවායේ අරමුණු මූලිකව වෙනස් වේ.
문자열 අස්ථිර (Immutable) වේ
String හි තවත් වැදගත් ලක්ෂණයක් වන්නේ එය අස්ථිර (immutable) බවයි. String වස්තුවක් නිර්මාණය වූ පසු, එහි අන්තර්ගතය වෙනස් කළ නොහැක.
උදාහරණයක් ලෙස:
String original = "hello";
original = original + " world";
මෙය මුල් 문자열ය වෙනස් කරමින් පෙනෙන්නට හැක, නමුත් වස්තවය වශයෙන්, නව String වස්තුවක් නිර්මාණය කර original වෙත නැවත පවරා ඇත.
මෙම අස්ථිරත්වය නිසා, String වස්තු ත්රෙඩ්-ආරක්ෂිත (thread-safe) වන අතර, ආරක්ෂාව සහ කෑෂ් (cache) ප්රතිඵලකරණය සඳහා වැදගත් භූමිකාවක් ගනී.
3. 문자열 සසඳීමේ ක්රම
== මෙහෙයුම්කරු සමඟ යොමු සසඳීම
== සංකේතය string වස්තු වල යොමු (ලිපිනය) සසඳයි. වෙනත් වචනයෙන්, අන්තර්ගතය එකසේ තිබුනත්, වස්තු වෙනස් නම් false ලබා දේ.
String a = "Java";
String b = new String("Java");
System.out.println(a == b); // false
මෙම උදාහරණයේ, a යනු ලිටරල් එකක් වන අතර b new භාවිතයෙන් නිර්මාණය කර ඇත, එබැවින් ඒවා වෙනත් වස්තු වෙත යොමු වන අතර ප්රතිඵලය false වේ. අවධානයෙන් සිටින්න: මෙය අන්තර්ගතය සසඳීමට සුදුසු නොවේ.
equals() සමඟ අන්තර්ගත සසඳීම
equals() යනු string අන්තර්ගතය සසඳීමට නිවැරදි ක්රමය වේ. බොහෝ අවස්ථාවල, මෙම ක්රමය නිර්දේශ කරයි.
String a = "Java";
String b = new String("Java");
System.out.println(a.equals(b)); // true
ඉහත පෙන්වා ඇති පරිදි, යොමු වෙනස් වුවත්, අන්තර්ගතය ගැලපේ නම් true ලබා දේ.
null සමඟ සසඳන විට වැදගත් සටහන්
පහත කේතය NullPointerException එකක් ඇති කරනු ඇත.
String input = null;
System.out.println(input.equals("test")); // Exception!
මෙය වැළැක්වීමට, constant.equals(variable) ආකාරයෙන් සසඳුම් ලිවීම නිර්දේශ කරයි.
System.out.println("test".equals(input)); // false (safe)
equalsIgnoreCase() සමඟ අකුරු-කේස් නොසැලකිලි සසඳීම
ඔබට අකුරු-කේස් නොසැලකිලි සසඳීම අවශ්ය නම් (උදාහරණයක් ලෙස, පරිශීලක නාම හෝ ඊමේල් ලිපින), equalsIgnoreCase() පහසු වේ.
String a = "Hello";
String b = "hello";
System.out.println(a.equalsIgnoreCase(b)); // true
කෙසේ වෙතත්, විශේෂ Unicode අවස්ථා (උදාහරණයක් ලෙස, තර්කිෂ් අකුර “İ”) තුළ හැසිරීම අපේක්ෂිත නොවිය හැකි බැවින්, ජාත්යන්තරීකරණය සඳහා අමතර අවධානය අවශ්ය වේ.
compareTo() සමඟ අක්ෂර-අනුක්රමික සසඳීම
compareTo() දෙකක් string අක්ෂර-අනුක්රමික (ශබ්දකෝෂ ක්රම) ලෙස සසඳයි සහ පහත පරිදි පූර්ණ සංඛ්යාවක් ලබා දේ:
- 0: සමාන
- ඍණ අගය: කැඳවන string එක පළමුව එනවා (කුඩා)
- ධන අගය: කැඳවන string එක පසු එනවා (විශාල)
String a = "apple"; String b = "banana"; System.out.println(a.compareTo(b)); // negative value ("apple" comes before "banana")
මෙය අක්ෂර-අනුක්රමික වර්ගීකරණය සහ පෙරහන් කිරීම සඳහා බොහෝවිට භාවිතා වේ, එසේම Collections.sort() සහ TreeMap තුළ යතුරු සසඳීම සඳහා අභ්යන්තරවද භාවිතා වේ.
4. ප්රායෝගික උදාහරණ
පරිශීලක ඇතුළත් කිරීම තහවුරු කිරීම (ලොගින් ක්රියාවලිය)
ඉතා සාමාන්ය භාවිතා අවස්ථාවක් වන්නේ පරිශීලක නාමය හෝ මුරපදය ගැලපේදැයි පරීක්ෂා කිරීමයි.
String inputUsername = "Naohiro";
String registeredUsername = "naohiro";
if (registeredUsername.equalsIgnoreCase(inputUsername)) {
System.out.println("Login successful");
} else {
System.out.println("Username does not match");
}
මෙම උදාහරණයේ පරිදි, අකුරු-කේස් නොසැලකිලිව string සසඳීමට අවශ්ය නම්, equalsIgnoreCase() භාවිතා කිරීම සුදුසු වේ.
කෙසේ වෙතත්, මුරපද සසඳීම සඳහා, ආරක්ෂණ හේතුන් සඳහා ලොකු සහ කුඩා අකුරු වෙනස් ලෙස සැලකිය යුතුය, එබැවින් equals() භාවිතා කරන්න.

ඇතුළත් කිරීම තහවුරු කිරීම (පෝරම සැකසීම)
උදාහරණයක් ලෙස, dropdown හෝ text box වලින් ලැබෙන ඇතුළත් අගයන් තහවුරු කිරීම සඳහා string සසඳීම භාවිතා වේ.
String selectedOption = request.getParameter("plan");
if ("premium".equals(selectedOption)) {
System.out.println("You selected the Premium plan.");
} else {
System.out.println("You selected a different plan.");
}
ප්රායෝගිකව, "constant".equals(variable) රටාව null නිරාකරණය කරන ආරක්ෂිත සසඳුමක් ලෙස පුළුල්ව භාවිතා වේ. පරිශීලක ඇතුළත් කිරීම සෑම විටම නොමැති විය හැකි බැවින්, මෙම රටාව NullPointerException වැළැක්වීමට උපකාරී වේ.
බහු කොන්දේසි සමඟ ශාඛාකරණය (Switch-වැනි තර්කය)
බහු සම්භවිත string අගයන් මත පදනම්ව ශාඛාකරණය කිරීමට අවශ්ය නම්, equals() සසඳුම් එකට එකතු කිරීම සාමාන්ය වේ.
String cmd = args[0];
if ("start".equals(cmd)) {
startApp();
} else if ("stop".equals(cmd)) {
stopApp();
} else {
System.out.println("Invalid command");
}
Java 14 සිට, string සඳහා switch ප්රකාශන නිල වශයෙන් සහය දක්වයි.
switch (cmd) {
case "start":
startApp();
break;
case "stop":
stopApp();
break;
default:
System.out.println("Unknown command");
}
සත්යතා සංසන්දනය සෘජුවම branching logic වලට බලපාන බැවින්, නිවැරදි අවබෝධයක් අත්යවශ්ය වේ.
null සමඟ සංසන්දනයෙන් ඇති වන Bugs සහ ඒවා වැළැක්වීම
පොදු අසාර්ථකත්වයක් යි app එකක් null වටිනාකමක් සමඟ සංසන්දනය කිරීම නිසා crash වීම.
String keyword = null;
if (keyword.equals("search")) {
// Exception occurs: java.lang.NullPointerException
}
එවැනි අවස්ථාවලදී, ඔබට මෙලෙස ලියා සුරක්ෂිතව සංසන්දනය කළ හැක:
if ("search".equals(keyword)) {
System.out.println("Executing search");
}
එසේම, ඔබට පළමුව null පරීක්ෂාවක් වඩාත්ව strict ලෙස සිදු කළ හැක.
if (keyword != null && keyword.equals("search")) {
System.out.println("Executing search");
}
null-safe code ලිවීම robust applications ගොඩනැගීමට අත්යවශ්ය කුසලතාවයක් වේ.
5. Performance සහ Optimization
සත්යතා සංසන්දනයේ Processing Cost
equals() සහ compareTo() සාමාන්යයෙන් හොඳින් optimize කර ඇති සහ වේගවත් ය. නමුත්, ඒවායේ අභ්යන්තරව character එකින් එක සංසන්දනය කරන බැවින්, දිගු සත්යතා හෝ විශාල datasets වලට performance impact එකක් ඇති විය හැක. විශේෂයෙන්ම, loops තුළ එකම සත්යතාව ආයෙබ්යගෝලනයෙන් සංසන්දනය කිරීම unintended performance degradation එකක් ඇති කළ හැක.
for (String item : items) {
if (item.equals("keyword")) {
// Be careful if this comparison runs many times
}
}
String.intern() සමඟ සංසන්දනය වේගවත් කිරීම
Java method String.intern() එකිනෙකට ඉදිරිපත් වන content ඇති සත්යතා JVM string pool හි register කර references share කරයි. මෙය භාවිතා කරමින්, == භාවිතයෙන් සංසන්දනය කිරීම possible විය හැකි අතර, නිශ්චිත scenarios වලදී performance benefits ලබා දිය හැක.
String a = new String("hello").intern();
String b = "hello";
System.out.println(a == b); // true
නමුත්, string pool හි අධික භාවිතය heap memory මත pressure වැඩි කළ හැකි බැවින්, මෙම approach well-defined use cases වලට සීමා කළ යුතුය.
equalsIgnoreCase() හි Pitfalls සහ Alternatives
equalsIgnoreCase() පහසුවෙන් භාවිතා කළ හැකි වුවද, එය අභ්යන්තරව case conversion සිදු කරන බැවින් එය equals() ට වඩා තරමක් expensive ය. performance-sensitive situations වලදී, සත්යතා advance ව normalize කර ඉන්පසු සංසන්දනය කිරීම බොහෝ විට වේගවත් ය.
String input = userInput.toLowerCase();
if ("admin".equals(input)) {
// Optimized comparison
}
සත්යතා advance ව normalize කර ඉන්පසු equals() භාවිතා කිරීමෙන්, ඔබට සංසන්දන efficiency වැඩි දියුණු කළ හැක.
StringBuilder / StringBuffer Effectively භාවිතා කිරීම
විශාල සංඛ්යාවක string concatenations සම්බන්ධ වන විට, String සෘජුව භාවිතා කිරීම සෑම විටම new objects create කරන අතර, memory සහ CPU overhead වැඩි කරයි. comparison logic සම්බන්ධ වුවද, best practice යි construction සඳහා StringBuilder භාවිතා කිරීම සහ comparison සඳහා values String ලෙස තබා ගැනීම.
StringBuilder sb = new StringBuilder();
sb.append("user_");
sb.append("123");
String result = sb.toString();
if (result.equals("user_123")) {
// Comparison logic
}
Caching සහ Preprocessing සමඟ Speed සඳහා Designing
එකම සත්යතා සංසන්දනයන් repeatedly සිදු වන විට, comparison results cache කිරීම හෝ maps (උදා: HashMap) preprocessing සඳහා භාවිතා කිරීම effective විය හැකි අතර, comparisons හි සංඛ්යාව අඩු කරයි.
Map<String, Runnable> commandMap = new HashMap<>();
commandMap.put("start", () -> startApp());
commandMap.put("stop", () -> stopApp());
Runnable action = commandMap.get(inputCommand);
if (action != null) {
action.run();
}
මෙම approach එකෙන්, equals() භාවිතයෙන් සත්යතා සංසන්දනය single map lookup එකකින් replace වන අතර, readability සහ performance දෙකම වැඩි දියුණු වේ.
6. Frequently Asked Questions (FAQ)
Q1. == සහ equals() අතර වෙනස කුමක්ද?
ඒ.
== ආධාරක සංසන්දනය කරයි (එනම්, එය දෙකම විචල්ය දෙකක් එකම මතක ලිපිනයකට යොමු වේදැයි පරීක්ෂා කරයි). එහෙත්, equals() සත්ය string අන්තර්ගතය සංසන්දනය කරයි.
String a = new String("abc");
String b = "abc";
System.out.println(a == b); // false (different references)
System.out.println(a.equals(b)); // true (same content)
එබැවින්, string අන්තර්ගතය සංසන්දනය කිරීමට අවශ්ය වන විට, සැමවිටම equals() භාවිතා කරන්න.
ප්රශ්න 2. equals() භාවිතා කිරීම සමහර විට null නිසා දෝෂ ඇති කරන්නේ ඇයි?
ඒ.
null මත ක්රමයක් කැඳවීම NullPointerException ඇති කරයි.
String input = null;
System.out.println(input.equals("test")); // Exception!
මෙම දෝෂය වැළැක්වීමට, පහත දැක්වෙන පරිදි ස්ථිරයක් මත equals() කැඳවීම වඩාත් ආරක්ෂිතයි.
System.out.println("test".equals(input)); // false (safe)
ප්රශ්න 3. මූලික අකුරු සලකා නොබලා string සංසන්දනය කරන්නේ කෙසේද?
ඒ.
උඩුකුරු සහ පහළ කුරු අකුරු අතර වෙනස්කම් නොසලකා equalsIgnoreCase() ක්රමය භාවිතා කරන්න.
String a = "Hello";
String b = "hello";
System.out.println(a.equalsIgnoreCase(b)); // true
කෙසේ වෙතත්, පූර්ණ-අනුපූර්ණ අකුරු හෝ නිශ්චිත විශේෂ Unicode අකුරු සමඟ, ප්රතිඵල සෑම විටම අපේක්ෂිත පරිදි නොවිය හැකි බව සිහි තබා ගන්න.
ප්රශ්න 4. string වර්ගීකරණ (lexicographical) අනුපිළිවෙලින් සංසන්දනය කරන්නේ කෙසේද?
ඒ.
string වල lexicographical අනුපිළිවෙල පරීක්ෂා කිරීමට අවශ්ය වන විට compareTo() භාවිතා කරන්න.
String a = "apple";
String b = "banana";
System.out.println(a.compareTo(b)); // negative value ("apple" comes before "banana")
ප්රතිලාභයේ තේරුම:
- 0 → සමාන
- ප්රතිලාභයක් → වම් string පළමුව එනවා
- ධනාත්මක ප්රතිලාභයක් → වම් string පසුව එනවා
මෙම ක්රමය වර්ගීකරණ මෙහෙයුම්වලදී සාමාන්යයෙන් භාවිතා වේ.
ප්රශ්න 5. string සංසන්දනය සඳහා හොඳම පුරුදු මොනවාද?
ඒ.
- අන්තර්ගත සංසන්දනය සඳහා සැමවිටම
equals()භාවිතා කරන්න "constant".equals(variable)භාවිතා කරමින් null ආරක්ෂාව සහතික කරන්න- මූලික-අකුරු-අනුකම්පා සංසන්දනය සඳහා,
equalsIgnoreCase()හෝtoLowerCase()/toUpperCase()භාවිතා කරමින් සමාන්යකරණය කරන්න - විශාල-පරිමාණ හෝ කාර්ය සාධන-මූලික සංසන්දන සඳහා,
intern()හෝ cacheකරණ උපාය මාර්ග සලකා බලන්න - සැමවිටම පාඨ ප්රකාශනය සහ ආරක්ෂාව අතර සමබරතාවය තබා ගන්න
7. නිගමනය
Java හි String සංසන්දනය සඳහා නිවැරදි ක්රමය තෝරා ගැනීම අත්යවශ්යයි
මෙම ලිපියෙහි, අන්තර්ගතයේ සිට ප්රායෝගික භාවිතයන් සහ කාර්ය සාධන සලකා බැලීම් දක්වා Java හි string සංසන්දනය ආවරණය කර ඇත. Java හි String ආධාරක වර්ගයක් වන බැවින්, වැරදි සංසන්දන ක්රමය භාවිතා කිරීමෙන් අනපේක්ෂිත හැසිරීම් ඇති විය හැකිය.
විශේෂයෙන්ම, == සහ equals() අතර වෙනස ආරම්භකයින්ගේ පළමුවන බෙදුම්වලින් එකක් ලෙස සලකනු ලැබේ. මෙම වෙනස තේරුම් ගැනීම සහ එක් එක් ක්රමය සුදුසු ලෙස භාවිතා කිරීම ආරක්ෂිත සහ විශ්වාසනීය කේත ලිවීම සඳහා අත්යවශ්යයි.
මෙම ලිපියෙන් ඔබ ඉගෙන ගත් දේ (පරීක්ෂා ලැයිස්තුව)
==ආධාරක (මතක ලිපින) සංසන්දනය කරයිequals()string අන්තර්ගතය සංසන්දනය කරයි සහ ආරක්ෂිතම විකල්පයයිequalsIgnoreCase()මූලික-අකුරු-අනුකම්පා සංසන්දනයට ඉඩ සලසයිcompareTo()lexicographical string සංසන්දනයට හැකියාව සපයයි"constant".equals(variable)null-ආරක්ෂිත සංසන්දනය සපයයි- කාර්ය සාධන-සංවේදී අවස්ථා සඳහා,
intern()සහ cacheකරණ උපාය මාර්ග ඵලදායී විය හැකිය
සැබෑ-ලෝක සංවර්ධනයේදී ගෙවන string සංසන්දනය දැනුම
string සංසන්දනය ලොගින් සත්යාපනය, ආදාන සත්යාපනය, දත්ත සමුදාය සෙවීම් සහ කොන්ඩිෂනල් බ්රැන්චිං වැනි දෛනික සංවර්ධන කාර්යයන්හි වැදගත් කාර්යභාරයක් ඉටු කරයි. මෙම සංකල්පවල තරබාරු තේරුමක් තිබේ නම්, ඔබට දෝෂ වැළැක්වීමට සහ ඔබේ කේතය නිවැරදි ලෙස හැසිරේ යැයි සහතික කිරීමට හැකිය.
string සමඟ වැඩ කරන කේතයක් ලියන විට, මෙම ලිපියෙහි ආවරණය වූ මූලධර්මවලට ආපසු යොමු වන්න සහ ඔබේ අරමුණට හොඳම ගැලපෙන සංසන්දන ක්රමය තෝරා ගන්න.


