Showing posts with label Java SE : 4 Collection Framework. Show all posts
Showing posts with label Java SE : 4 Collection Framework. Show all posts

October 27, 2012

Collections Utility Class 2

ပြီးခဲ့သော အခန်းတွင် Collections ကလပ်စ်အား အသုံးပြု၍ Collection Interface အား အသုံးပြုနိုင်သော အလဂိုရီဇင်အား လေ့လာခဲ့သည်။ ယခုတစ်ခေါက်တွင်လည်း Collections ၏ လုပ်ဆောင်ချက်များအား ဆက်လက်၍ ရေးသားသွားပါမည်။


ဖွဲ့စည်းပုံအား သိရှိနိုင်သော လုပ်ဆောင်ချက်များ

Collections ၏ frequency နှင့် disjoint အလဂိုရီဇင်များသည် Collection များ၏ ဖွဲ့စည်းပုံကို သိရှိနိုင်သော လုပ်ဆောင်ချက်များ ဖြစ်ကြသည်။ Collections#frequency သည် Collection တစ်ခုအတွင်း Object တစ်ခုသည် အကြိမ်မည်မျှပါဝင်သည်ကို သိရှိနိုင်မည် ဖြစ်သည်။ တဖန် disjoint လုပ်ဆောင်ချက်သည် Collection နှစ်ခု အတွင်း ပတ်သက်မှု့ ရှိမရှိ သိရှိနိုင်မည် ဖြစ်သည်။

FrequencySample.java
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class FreequencySample {

    static final String [] STRINGS = {"1","2","1","1","2","3","4","2","1"};
    public static void main(String[] args) {
        List<String> list = Arrays.asList(STRINGS);
        int count = Collections.frequency(list, "1");
        System.out.println("Frequency of 1 is " + count);
    }
}
အထက်ပါ နမှုနာအတိုင်း List Object တစ်ခုဖြစ်သော list အတွင်းတွင် "1" ဘယ်နှစ်ကြိမ်ပါသလဲ ဆိုတာကို စာကြောင်း ၁၀ တွင် ရေးသားထားသည့်အတိုင်း Collections.frequency လုပ်ဆောင်ချက်ဖြင့် သိရှိနိုင်ပါသည်။ ပဋ္ဌမ Argument မှာ ရှာဖွေမည့် List အား ရေးသားရမည် ဖြစ်ပြီး၊ ဒုတိယ Argument တွင် ရှာဖွေမည့် Object အား ရေးသားရမည် ဖြစ်ပါသည်။

DisjointSample.java
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class DisjointSample {

    static final String[] STRINGS1 = { "1", "2", "1", "1", "2", "3", "4", "2",
            "1" };
    static final String[] STRINGS2 = { "1", "2", "5" };
    static final String[] STRINGS3 = { "6", "7", "8" };

    public static void main(String[] args) {
        List<String> list1 = Arrays.asList(STRINGS1);
        List<String> list2 = Arrays.asList(STRINGS2);
        List<String> list3 = Arrays.asList(STRINGS3);

        System.out.println("List1 disjoint List2 : "
                + Collections.disjoint(list1, list2));
        
        System.out.println("List2 disjoint List3 : "
                + Collections.disjoint(list2, list3));
    }

}

လစ်တစ်ခုနှင့် တစ်ခု ပတ်သက်မှု့ရှိမရှိအား Collections#disjoint လုပ်ဆောင်ချက်ကို အသုံးပြုနိုင်ပါမည်။ အကယ်၍ လစ်နှစ်ခုအတွင်း တူညီသော Element အချို့ပါဝင်ချင်း မရှိပါက၊ ပတ်သက်မှု့ မရှိပါက true ကို ရရှိမည် ဖြစ်ပြီး၊ လစ်တစ်ခုအတွင်းပါဝင်သော အချို့သော Element များက အခြားလစ်တစ်ခုအတွင်း ပါဝင်ပါက false ကို ရရှိနိုင်မည် ဖြစ်သည်။ အထက်ပါ နမှုနာအား Run ကြည့်သောအခါ အောက်ပါအတိုင်း တွေ့ရှိရမည် ဖြစ်ပါသည်။




အသုံးများသော အခြားသော လုပ်ဆောင်ချက်များ

Collections Class အတွင်းတွင် အထက်ဖော်ပြပါ လုပ်ဆောင်ချက်များအပြင် အခြားသော အသုံးဝင်သော လုပ်ဆောင်ချက်များကို ပြင်ဆင်ထားပါသည်။

အမည် ရှင်းလင်းချက်
reverse Collectionအတွင်းရှိ Element များ၏ အစီအစဉ်အား ပြောင်းပြန် ပြန်ပြီး စီစဉ်ရာတွင် အသုံးပြုနိုင်သောလုပ်ဆောင်ချက် တစ်ခုဖြစ်ပါသည်။
fill List တစ်ခုအတွင်းရှိ Element များအား Object တစ်ခုဖြင့် အစားထိုးနိုင်၏။ ဤလုပ်ဆောင်ချက်သည် List တစ်ခုအား ပြန်လည် Initialize လုပ်ရာတွင် အသုံးဝင်မည် ဖြစ်ပါသည်။
copy List တစ်ခုမှ အခြားသော List တစ်ခုဆီသို့ ကော်ပီကူးရာတွင် အသုံးပြုနိုင်ပါသည်။ Argument အနေဖြင့်List နှစ်ခုကို လိုအပ်မည် ဖြစ်ပါသည်။ ကော်ပီ List နှင့် မှုရင်း List တို့ဖြစ်ကြ၏။ ကော်ပီ List ၏ size သည် အနည်းဆုံး မှုရင်း List လောက်ရှိရန် လိုအပ်ပါသည်။ မှုရင်း List ပမာနထက် ပိုများသွားပါက ပိုသော နေရာများအား အကျိုးသက်ရောက်မှု့ ရှိမည် မဟုတ်ပေ။
swap List တစ်ခုအတွင်းရှိ Element များအား နေရာပြောင်းရာတွင် အသုံးပြုနိုင်မည် ဖြစ်ပါသည်။ ပဋ္ဌမ Argument မှာ List Object ဖြစ်ပြီး၊ နောက် Argument နှစ်ခုမှာ ပြောင်းလိုသည့် နေရာ (index) များ ဖြစ်ကြသည်။ အကယ်၍ ပြောင်းရွှေ့လိုသော နေရာနှစ်ခုသည် List ၏ size ထက်များနေပါက IndexOutOfBoundException ကို ဖြစ်ပေါ်စေမည် ဖြစ်၏။
Colletions.swap (list, 0, 4) ဟု ရေးသားထားပါက list ၏ 0 နေရာရှိ Element နှင့် 4 နေရာရှိ Element တို့အား အသီးသီး နေရာပြောင်းပေးမည် ဖြစ်သည်။
["1","2","3","4","5"] ဟုရှိခဲ့ပါက swap လုပ်ပြီးသောအခါ ["5","2","3","4","1"] ဖြစ်သွားမည် ဖြစ်ပါသည်။
addAll addAll လုပ်ဆောင်ချက်သည် Collection တစ်ခုအတွင်းကို၊ ဒုတိယ Argument ဖြစ်သော Varargs အတွင်းမှ Object များအား တစ်ပြိုင်နက်တည်း ထည့်သွင်းနိုင်မည် ဖြစ်ပါသည်။ 
min Collectionအတွင်းရှိ သဘာဝအစီအစဉ် အတိုင်းစီစဉ်သောအခါ အကြီးမားဆုံး Element ကို ရရှိမည် ဖြစ်ပါသည်။
max Collection အတွင်းရှိ သဘာဝအစီအစဉ် အတိုင်း စီစဉ်သောအခါအသေးငယ်ဆုံး Element ကို ရရှိမည် ဖြစ်သည်။


အထူးအသုံးပြုပုံများ

အထက်ဖော်ပြပါ အသုံးပြုနည်းများမှာပုံမှန် ကော်လက်ရှင်များအား အသုံးပြုသော အသုံးပြုနည်းများဖြစ်ကြသည်။ သို့ရာတွင် Multi Thread Programming များတွင်၎င်း၊ Concurrency Framework များတွင်၎င်း၊ Parallel Processing များတွင်၎င်း အစရှိသည့် သီးခြားအခြေအနေများတွင် အသုံးပြုလိုသည့် အခါများလည်း ရှိတတ်ပေသည်။ ထိုအခါမျိုးတွင်ရိုးရိုး Collection များအား အသုံးပြု၍ မရနိုင်ပေ။ အဘယ်ကြောင့်ဆိုသော် Collection Framework အတွင်းရှိ General Purpose Implementations များသည် Thread Safe မဟုတ်သောကြောင့် ဖြစ်သည်။

Thread Safe ဆိုသည်မှာ Multi Thread များအကြားတွင် အသုံးပြုရာတွင် အမှားအယွင်းမရှိစေရန် ကာကွယ်ပေးထားခြင်း ဖြစ်၏။ ဒီလိုဆိုရင် ဘာလို့ Collection တွေအားလုံးမှာ Thread Safe မလုပ်ထားတာလဲ ဟု မေးစရာရှိပါလိမ့်မည်။ မလိုအပ်ပဲ Thread Safe လုပ်ထားပါက Synchronization အစရှိတဲ့ လေးလံတဲ့ အလုပ်များကို မလိုအပ်ပဲ လုပ်နေရမည် ဖြစ်သောကြောင့် ဖြစ်သည်။

အချို့သောသူများရှိပါသည်။ General Purpose Collection များအား ဘုမသိဘမသိ Multi Thread Program အတွင်းမှာ သွားသုံးပြီး Collection ဟာ Thread Safe မဟုတ်ဘူးဆိုပြီး ထအော်နေသူများရှိပါသည်။

Collections Utility Class တွင် အထက်ပါ အထူးအခြေအနေများတွင် အသုံးပြုနိုင်ရန် လုပ်ဆောင်ချက်များကိုလည်း ပြင်ဆင်ထားပါသည်။


Singleton

Singleton သည် Design Pattern တစ်မျိုးဖြစ်ပြီး၊ တစ်ခုထက်ပိုပြီး Instance ကို မရေးသား လိုသည့်အခါမျိုးတွင် အသုံးပြုလေ့ရှိ၏။ Collection Framework တွင်လည်း တစ်ခုတည်းသော Collection Instance များအား အသုံးပြုနိုင်ရန် Collections ကလပ်စ်တွင် ပံ့ပိုးပေးထားပါသည်။

public static <T> Set<T> singleton (T o)
public static <T> List<T> singletonList(T o)
public static <K,V> Map<K,V> singletonMap(K key, V value) 

လုပ်ဆောင်ချက်များ၏ အမည် အတိုင်း singleton သည် Object တစ်ခုသာပိုင်ဆိုင်သော Set အင်းစတန့်စ်အား ပြန်ပေးမည်ဖြစ်ပြီး၊ singletonList သည် List အင်းစတန့်စ်အား၎င်း၊ singletonMap သည် Map အင်းစတန့်စ် အား၎င်း ပြန်ပေးမည် ဖြစ်သည်။ singleton လုပ်ဆောင်ချက်များဖြင့် ပြုလုပ်ထားသော တောက်လျှောက် တစ်ခုတည်းသော အင်းစတန့်စ်အဖြစ် အသုံးပြုနိုင်မည် ဖြစ်သည်။ အကယ်၍ singleton ဖြင့် လုပ်ယူထားသော Collection ပြုပြင်ပြောင်းလည်း ကြည့်ပါက java.lang.UnsupportedOperationException အား ဖြစ်ပေါ်စေမည် ဖြစ်ပါသည်။

singleton လုပ်ဆောင်ချက်ဘယ်လိုနေရာတွေမှာ အသုံးဝင်သလဲ ဆိုတာ သိပ်ပြီး မသိ။ ဘာတွေကောင်းလဲ ဘယ်နေရာမှာ သုံးသင့်သလဲနမှုနာကို ရေးရင်းလေ့လာကြည့်ပါဦးမည်။

SingletonSample.java
iimport java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

public class SingletonSample {
    
    public static void main(String[] args) {
        
        final Set<String> set = new HashSet<>(Arrays.asList("Element"));
        Set<String> singleton = Collections.singleton("Element");
        
        System.out.println(set);
        System.out.println(singleton);
    }
}

Element တစ်ခုသာပိုင်၍ ပြောင်းလည်းမရနိုင်သော Set တစ်ခုကို လိုချင်ပါက အထက်ပါ စာကြောင်း ၁၀အတိုင်း final တတ်၍ရေသားနိုင်ပါသည်။ ဘာကြောင့် Singleton ကို လိုအပ်ရသနည်း။ ရုတ်တရက်ကြည့်လျှင် Arrays ဖြင့် List ကို ရယူ၍ HashSet တွင် အစားထိုးနေရသဖြင့် Step နည်းနည်းများများ ရေးရသည်ထက် ပိုပြီးထူးသည်ဟု မမြင်ပါ။ Eclipse Debug Mode ဖြင့် ၎င်း set နှင့် singleton တို့အား ကြည့်ကြည့်ပါမည်။

set အား ကြည့်ထားသော ပုံဖြစ်ပါသည်။
singleton အား ကြည့်ထားသော ပုံဖြင့်ပါသည်။

အထက်ပုံ နှစ်ခုအား ယှဉ်ကြည့်ပါက သိနိုင်မည် ဖြစ်ပါသည်။ set သည် အတွင်းပိုင်းတွင် နေရာ အများကြီးကို ယူထားရပါသည်။ သို့ရာတွင် singletone အတွင်းမှာမူ String element ဖြစ်သော အင်းစတန့်စ် တစ်ခုသာပိုင်ဆိုင်၏။ ပြုပြင်ပြောင်းလည်း၍မရနိုင်သော Element တစ်ခုတည်းသာပိုင်ဆိုင်သော Set ခြင်း တူသော်လည်း singleton သည် အလွန်ပေါ့ပါးသည်ဆိုသည်ကို တွေ့နိုင်မည် ဖြစ်သည်။

ဤနည်းအားဖြင့် Element တစ်ခုတည်းသာပိုင်၍ ပြောင်းလည်းမရနိုင်သော Set Object အားအသုံးပြုလိုပါက singleton အား အသုံးပြုခြင်းက ရိုးရိုး HashSet အား new လုပ်ခြင်းထက် ပို၍ Performance ကောင်းကြောင်း တွေးမြင်နိုင်မည် ဖြစ်ပါသည်။ 


Unmodifiable Collections

ပရိုဂရမ်များ ရေးသားရာတွင် ရေးရင်းရေရင်းရှုပ်ထွေးလာပါက ပရိုဂရမ်မာက မျှော်လင့်မထားသော အရာများ ဖြစ်ပေါ်လေ့ရှိ၏။ ရန်ဖန်ရံခါ အစပိုင်းတွင် လိုအပ်သော အချက်အလက်များအား တွက်ယူ၍ နောက်ပိုင်းတွင် ထိုအချက်အလက်များအား အကြိမ်ကြိမ်ခေါ်ယူ သုံးဆွဲလိုသည့် အခါမျိုးရှိ၏။ ထိုအချက်အလက်များအား ပြောင်းလည်း၍ မရအောင် လုပ်ထားလိုသည့် အခါမျိုးရှိ၏။ Collections တွင် ထိုအခါမျိုးတွင် အသုံးပြုနိုင်ရန် လုပ်ဆောင်ချက်များကို ပြင်ဆင်ထားပါသည်။

public static <T> Collection<T> unmodifiableCollection(Collection<T> c)
public static <T> List<T> unmodifiableList(List<T> list)
public static <K,V> Map<K,V> unmodifiableMap(Map<K,V> m)
public static <T> Set<T> unmodifiableSet(Set<T> s)
public static <K,V> SortedMap<K,V> unmodifiableSortedMap(SortedMap<K,V> m)
public static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s)

အထက်ပါ လုပ်ဆောင်ချက်များအား အသုံးပြုခြင်းအားဖြင့် Collection Instance များအား ပြုပြင်ပြောင်းလည်း၍ မရနိုင်အောင် ပြောင်းလည်းနိုင်ပါသည်။


စကားပို : Multithread Programming

အမှန်ဆို ဒီနေရာတွင် Synchronization နှင့် ပတ်သက်ပြီး မရေးလိုသေးပါ။ Multithread Programming နှင့် Parallel Programming အကြောင်း Concurrency Framework အကြောင်း ရေးရင်း Thread Safe နှင့် Synchronization အကြောင်းကို ရေးလိုပါသည်။ သို့ရာတွင် Collections အကြောင်း ရေးရင်း Synchronization အကြောင်း တစ်ခုတည်း ချန်မထားချင်သောကြောင့် အနည်းအကျဉ်း ထိတွေ့သွားပါမည်။

ကွန်ပျူတာပေါ်တွင်အပလီကေးရှင်းများအား အလုပ်လုပ်စေရာတွင် File ပေါ်တွင် သိမ်းဆည်းထားသော Commands နှင့် အချက်အလက်များအား Virtual Memory အပေါ်ခေါ်ယူ၍ အလုပ်လုပ်စေပြီး လိုအပ်သလို Hard Desk အပေါ်တွင် သိမ်းဆည်းထားသော Data များအား ဆက်သွယ် အသုံးပြုလေ့ရှိ၏။ ထိုကဲ့သို့ အပလီကေးရှင်း တစ်ခုအား အလုပ်လုပ်စေသည့် Unit အား Process ဟုခေါ်ဆိုပါသည်။
CPU ၏ အမြန်နှုန်းနှင့်စာလျှင် Hard Disk ပေါ်မှ အချက်အလက်များအား ခေါ်ယူသည့် Speed သည် အလွန်နောက်ကျလေ့ရှိ၏။ ထိုကဲ့သို့ စောင့်နေသောအချိန်အတွင်းတွင် အခြားသော အလုပ်များကို ခိုင်းစေထားခြင်းသည် လုပ်ဆောင်ချိန်ကို လျှင်မြန်စေမည် ဖြစ်သည်။ ဤနည်းအားဖြင့် Process တစ်ခု အလုပ်လုပ်နေစဉ် အခြားသော Process များအား ပြိုင်တူ အလုပ်လုပ်စေသော Parallel Processing ကို ပေါ်ပေါက်စေခဲ့ပါသည်။

Process သည် ပရိုဂရမ်တစ်ခုအား အလုပ်လုပ်စေရန် သီးခြား မံမိုရီဧရိယာကို ပိုင်ဆိုင်ပြီး တစ်ခုနှင့်တစ်ခု လွတ်လပ်စွာ အလုပ်လုပ်စေနိုင်သလို အခြားတစ်ဘက်မှာလည်း တစ်ခုစီ သီးခြား မံမိုရီကို ပေးထားရတဲ့အတွက် တစ်ခုနှင့်တစ်ခု ပြောင်းလည်းရာတွင် လေးလံတက်ပါသည်။ ထို့ကြောင့် အလုပ်များကို သီးခြားလုပ်နိုင်စေပြီး Memory နှင့် Data အစရှိသော Resource များအား ဘုံအနေဖြင့် အသုံးပြုနိုင်သော Thread များကို ဖန်တီးလာကြပါသည်။ ဤကဲ့သို့ Thread တစ်ခု အလုပ်လုပ်နေစဉ် အခြားသော Thread များကိုလည်း တပြိုင်တည်း အသုံးပြုနိုင်သော ပရိုဂရမ်မင်း နည်းပညာ ဖြစ်သော Multithread Programming ကို ပေါ်ပေါက်စေလာခဲ့ပါသည်။


Synchronization

Java သည်လည်း Multithread Programming အားပေါ်ပြီး မကြာခင်ကတည်းက ပံ့ပိုးပေးခဲ့ပါသည်။ Thread တစ်ခု အလုပ်လုပ်နေချိန်တွင် လေးလံသော အလုပ်အား အခြားသော Threadဖြင့်ခိုင်းထားပြီး ထို Thread အလုပ်ပြီးခါမှ အခြားသော Thread ဖြင့် ပူးပေါင်းဆောင်ရွက်စေခြင်း ဖြစ်သည်။ သို့ရာတွင် Object တစ်ခုအား Thread များမှ အပြိုင် Update လုပ်သည့်အခါမျိုး ရှိပေလိမ့်မည်။ ထိုအခါမျိုးတွင် Object အား အစီအစဉ်တကျ Update လုပ်စေရန် စီမံဖို့လိုအပ်ပါသည်။ ဤကဲ့သို့ စီမံခြင်းအား Synchronization ဟုခေါ်ဆိုပါသည်။

Collections ကလပ်စ်တွင် Synchronized Collection Object များအဖြစ် ပြောင်းလည်းပေးနိုင်သော လုပ်ဆောင်ချက်များအား ပြင်ဆင်ထားပါသည်။ ၎င်းတို့မှာ အောက်ပါအတိုင်းဖြစ်၏။

static <T> Collection <T> synchronizedCollection (Collection <T> c)
static <T> List <T> synchronizedList (List <T> list)
static <T> Set <T> synchronizedSet (Set <T> s)
static <K,V> Map <K,V> synchronizedMap (Map <K,V> m)
static <T> SortedSet <T> synchronizedSortedSet (SortedSet <T> s)
static <K,V> SortedMap <K,V> synchronizedSortedMap (SortedMap <K,V> m)

Thread တစ်ခုနှင့် တစ်ခုအကြားတွင် စနစ်တကျ အလုပ်မလုပ်စေသောအခါ မည်ကဲ့သို့ အစဉ်မပြေမှု့များကို ဖြစ်ပွားစေသနည်း။ လက်တွေ့ရေးသားကြည့်ပါမည်။

ThreadSafeSample1.java
import java.util.LinkedList;
import java.util.List;

public class ThreadSafeSample1 extends Thread{

    static int total = 0;
    private final List<?> list;
    
    public ThreadSafeSample1(List<?> list) {
        this.list = list;
    }
    
    @Override
    public void run() {
        int count = 0;
        while(list.remove(null))
            count++;
        
        System.out.println("Consume " + count + " Element");
        
        synchronized (this.getClass()) {
            total += count;
        }
    }
    
    public static void main(String[] args) throws InterruptedException {
        
        List<Thread> threads = new LinkedList<>();
        List<?> list = new LinkedList<>();

        for (int i=0; i < 100000; i++)
            list.add(null);
        
        for (int i=0; i < 5; i++)
            threads.add(new ThreadSafeSample2(list));
        
        for (Thread t : threads)
            t.start();
            
        for (Thread o : threads)
            o.join();

        System.out.println("Total is " + total);
    }
}
အထက်ပါ နမှုနာတွင် MultiThread အား အသုံးပြုနိုင်ရန် Threadကလပ်စ်အား Extends လုပ်ပြီး ရေးသား ထားပါသည်။ List တစ်ခုအား Constructor ဖြင့် ရယူပြီး Member Variable ဖြစ်သော list တွင် အစားထိုးပါသည်။ တဖန် Thread အနေဖြင့် အလုပ်လုပ်စေမည့် run လုပ်ဆောင်ချက်အား override လုပ်၍၊ list အတွင်းမှ null အား remove လုပ်စေပြီး count ဖြင့် အကြိမ်အား မှတ်သားထားစေပါသည်။ နောက်ဆုံးတွင် count အား System.out လုပ်စေပြီး၊ static variable ဖြစ်သော total တွင် ပေါင်း၍ အစားထိုးစေပါသည်။ ဤနည်းအားဖြင့် remove လုပ်သောအကြိမ်များအား total တွင် သွားပေါင်းထားမည် ဖြစ်ပါသည်။

ကျွှန်တော်တို့ ဒီနေရာတွင် စမ်းသပ်လိုသည်မှာ List အား ဖြစ်ပါသည်။ ထိုအတွက် စာကြောင်း List တစ်ခုအား new လုပ်ကာ အကြိမ် ၁သိန်း Loop လုပ်၍ null များအား ဖြည့်ထားစေပါသည်။ ပြီးပါက ထို list အား Thread ၅ခုဖြင့် အလုပ် လုပ်စေပါသည်။ Thread များသည် list အတွင်းမှ null များအား မကုန်မခြင်း remove လုပ်သွားမည် ဖြစ်သည်။ တစ်ခုခြင်း အလုပ်လုပ်သော အကြိမ်မှာ မတူညီနိုင်ပေမယ့် မှန်မှန်ကန်ကန် အလုပ်လုပ်သွားပါက နောက်ဆုံး အားလုံးပေါင်းရလဒ်သည် ၁သိန်း ဖြစ်ရမည်ဖြစ်သည်။ ကျွှန်တော်တို့ အထက်ပါ ပရိုဂရမ်အား စမ်းသပ်ကြည့်ပါမည်။


မှန်ကန်စွာ ဖော်ပြနိုင်ခြင်း မရှိကြောင်း တွေ့ရမည် ဖြစ်သည်။ အဘယ်ကြောင့်ဆိုသော် List သည် Thread Safeမဟုတ်သောကြောင့် ဖြစ်သည်။ List အား Thread Safe ဖြစ်အောင် ပြုပြင်ရေးသားကြည့်ပါမည်။

ThreadSafeSample2.java
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

public class ThreadSafeSample2 extends Thread{

    static int total = 0;
    private final List<?> list;
    
    public ThreadSafeSample2(List<?> list) {
        this.list = list;
    }
    
    @Override
    public void run() {
        int count = 0;
        while(list.remove(null))
            count++;
        
        System.out.println("Consume " + count + " Element");
        
        synchronized (this.getClass()) {
            total += count;
        }
    }
    
    public static void main(String[] args) throws InterruptedException {
        List<Thread> threads = new LinkedList<>();
        List<?> list = Collections.synchronizedList(new LinkedList<>());

        for (int i=0; i < 100000; i++)
            list.add(null);
        
        for (int i=0; i < 5; i++)
            threads.add(new ThreadSafeSample2(list));
        
        for (Thread t : threads)
            t.start();
            
        for (Thread o : threads)
            o.join();

        System.out.println("Total is " + total);
    }

}
အရင်ရေးထားသော နမှုရာအား စာကြောင်း ၂၉တွင် Collections#synchronizedList အား အသုံးပြု၍ List အား Thread Safe ဖြစ်အောင် ပြုပြင်ရေးထားပါသည်။ ၎င်းနမှုနာအား အလုပ်လုပ်ခိုင်း ကြည့်ပါမည်။

အထက်ပါအတိုင်း Total အား အကြိမ် ၁သိန်းဟု မှန်ကန်စွာ ဖော်ပြနိုင်သည်ကို တွေ့ရပါမည်။

ကိုးကား
http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html


ဆက်ပါဦးမည်။ လေးစားစွာဖြင့်။ 
မင်းလွင်

October 21, 2012

Collections Utility Class

ပြီးခဲ့သော အခန်းဆက်ဖြင့် ကိန်းစဉ်များအား အသုံးပြုနိုင်သော Arrays Utility Class အကြောင်းကို ဖော်ပြခဲ့၏။ Collection Framework လက်ထက်ရောက် ပြန်တော့လည်း Collection များအား အသုံးပြုနိုင်သော Collections Utility Class ကို ပြင်ဆင်ထားခဲ့ပါသည်။ Collections Class ကိုစတင်ပြင်ဆင်လာခဲ့သည်မှာ Java SE 1.2 ကတည်းက ဖြစ်ပြီး၊ Collection Interface များအား အသုံးပြုနိုင်သော Static Method အမျိုးမျိုးကို ပြင်ဆင်ထားပါသည်။

တစ်ခုသတိထားရန်လိုအပ်သည်မှာ အသုံးပြုမည့် Collection Interface ၏ Instance သည် null ဖြစ်နေပါက၊ NullPointerException ကို ပြန်ပြီး Throw လုပ်မည် ဖြစ်ပါသည်။

ဤတစ်ခေါက်တွင်လည်း အသုံးပြုပုံအပေါ်မှုတည်ပြီး Collectionsကလပ်စ်အား လေ့လာသွားပါမည်။


Sorting

Collections တွင်လည်း Arrays ကလပ်စ်ကဲ့သို့ပင် Collection များအား Sort လုပ်နိုင်ရန် sort လုပ်ဆောင်ချက်အား ပြင်ဆင်ထား၏။


static<T extends Comparable<? super T>> void sort (List<T> list)


List<T> list အတွင်းရှိ အချက်အလက်များအား Natural Order အတိုင်း Sort လုပ်ရာတွင် အသုံးပြုနိုင်ပါသည်။ အသုံးပြုမည့် Order များ Ascending Order အား အသုံးပြုသွားမည် ဖြစ်ပါသည်။

SortSample1.java
package com.mmju.eja.ep1.collections;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class SortSample1 {

 static final Object[][] OBJECTS = { { "Name1", "100.05" },
   { "Name2", "100.00" }, { "Name1", "100.01" },
   { "name1", "100.00" }, { "name3", "100.00" } };

 static class Data implements Comparable<Data> {

  String name;
  double value;

  public Data(String name, double value) {
   this.name = name;
   this.value = value;
  }

  @Override
  public int compareTo(Data o) {
   int result = 0;
   if (0 != (result = this.name.compareTo(o.name))) {
    return result;
   }
   return Double.valueOf(this.value)
     .compareTo(Double.valueOf(o.value));
  }
  
  public void doOutput() {
   System.out.println(this.name + " : " + String.valueOf(this.value));
  }

 }
 
 public static void doOutput(String msg, List<Data> datas) {
  System.out.println("------ " + msg + " START ------" );
  for(Data d : datas)
   d.doOutput();
  System.out.println("------ " + msg + " END --------\n" );
 }

 public static void main(String[] args) {

  List<Data> datas = new ArrayList<>();

  for (Object[] obj : OBJECTS) {
   datas.add(new Data((String) obj[0], Double.valueOf((String) obj[1])
     .doubleValue()));
  }
  
  doOutput("Before Sorting", datas);
  
  Collections.sort(datas);
  
  doOutput("After Sorting", datas);
 }

}
 
အထက်ပါ နမှုနာအား ကြည့်ပါ။ Data အား အသုံးပြုသော List အား Sort လုပ်ရန်အတွက် Data ကလပ်စ်သည် Comparable Interface အား implement လုပ်ထားရန်လိုအပ်ပါသည်။ ထို့အတွက် စာကြောင်း ၁၃တွင် implements Comparable<Data> ဟု ရေးသားထားပါသည်။ Comparable အင်တာဖေစ်အား Implement လုပ်ထားသောကြောင့် ၎င်း၏ လုပ်ဆောင်ချက်ဖြစ်သော compareTo အား ဖြည့်စွက်ရေးသားရန် လိုအပ်လာပါသည်။ ထို့အတွက် စာကြောင်း ၂၃မှ ၃၁အထိ compareTo အား override လုပ်ကာ ရေးသားထားပါသည်။ ဤကဲ့သို့ Compareble အား implement လုပ်ထားသောကြောင့် Collections.sort အား အသုံးပြုနိုင်ခြင်း ဖြစ်ပါသည်။


static<T> void sort (List<T> list, Comparator<? super T> c)


ကိုယ်ပိုင် Comparator အား ပြင်ဆင်၍ List အတွင်းရှိ Object များအားလည်း Sort လုပ်နိုင်မည် ဖြစ်သည်။

SortSample2.java
package com.mmju.eja.ep1.collections;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class SortSample2 {

 static final Object[][] OBJECTS = { { "Name1", "100.05" },
  { "Name2", "100.00" }, { "Name1", "100.01" },
  { "name1", "100.00" }, { "name3", "100.00" } };

 static class Data {

  String name;
  double value;

  public Data(String name, double value) {
   this.name = name;
   this.value = value;
  }

  public void doOutput() {
   System.out.println(this.name + " : " + String.valueOf(this.value));
  }

 }
 
 public static void doOutput(String msg, List<Data> datas) {
  System.out.println("------ " + msg + " START ------" );
  for(Data d : datas)
   d.doOutput();
  System.out.println("------ " + msg + " END --------\n" );
 }

 public static void main(String[] args) {

  List<Data> datas = new ArrayList<>();

  for (Object[] obj : OBJECTS) {
   datas.add(new Data((String) obj[0], Double.valueOf((String) obj[1])
     .doubleValue()));
  }
  
  doOutput("Before Sorting", datas);
  
  Collections.sort(datas, new Comparator<Data>() {

   @Override
   public int compare(Data o1, Data o2) {
    int result = 0;
    if (0 != (result = o1.name.compareTo(o2.name))) {
     return result;
    }
    return Double.valueOf(o1.value)
      .compareTo(Double.valueOf(o2.value));
   }
  });
  
  doOutput("After Sorting", datas);
 }

}
 
အကယ်၍အကြောင်းအမျိုးမျိုးကြောင့် Sort လုပ်လိုသော Object အား Comparable Interface အဖြစ် Implement မလုပ်နိုင်ပါက ကိုယ်ပိုင် Comparator အင်တာဖေစ်အား ပြင်ဆင်၍ အသုံးပြုနိုင်ပါသည်။ အထက်ပါ နမှုနာထဲတွင် Data Class သည် Comparable အား Implement ပြုလုပ်ထားခြင်း မရှိပါ။ သို့ရာတွင် စာကြောင်း ၄၈ Collections#sort တွင် Comparator အင်တာဖေစ်၏ Object အား တိုက်ရိုက် ဖြည့်စွက် ရေးသားထားပါသည်။ စာကြောင်း ၅၀မှ ၅၈အထိသည် လက်တွေ့အသုံးပြုမည့် Comparator#compare လုပ်ဆောင်ချက်ဖြစ်ပြီး Comparator အား အသုံးပြုရာတွင် မရှိမဖြစ် ဖြည့်စွက်ရေးသားရန် လိုအပ်သော လုပ်ဆောင်ချက်ဖြစ်၏။

ဤနမှုနာထဲတွင် Comparator ၏ အော့ဘဂျက်အား Sort လုပ်ရာတွင်သာအသုံးပြုလိုပါသဖြင့် အပြင်ပိုင်းတွင် instance တစ်ခုအား တကူးတက မရေးသားတော့ပဲ Collection.sort အတွင်းတွင် တိုက်ရိုက် new လုပ် ရေးသားခဲ့ပါသည်။ javascript နဲ့ python ရေးသားသူတွေအတွက်တော့ ရင်းနှီးပြီးသား ရေးသားပုံဖြစ်ပါသည်။

အကယ်၍အကြိမ်ကြိမ် Sortလိုသည့်အခါမျိုးဆိုပါက Comparator အား implement လုပ်ထားသော Class တစ်ခုအားရေးသားထားပြီး အသုံးပြုပါက Sort လုပ်သည့်အခါတွင် အကြိမ်ကြိမ် ရေးသားရန် လိုအပ်တော့မည်မဟုတ်ပေ။ ထိုအတွက် ပြုပြင်ရန်လိုအပ်ပါက ထိုကလပ်စ်အား ပြုပြင်ရုံနှင့် ပြီးမည်ဖြစ်ပါသည်။

အထက်ပါ လုပ်ဆောင်ချက်နှစ်မျိုးလုံးသည် List အား Sort လုပ်နေသည်မှာ တူသော်လည်း မတူညီသည်မှာ Comparator အား အသုံးပြု၍ Sort လုပ်ခြင်းနှင့် Comparable အား အသုံးပြု၍ Sort လုပ်ခြင်း ဖြစ်၏။ Comparator အင်တာဖေစ်နှင့် Comparable အင်တာဖေစ်သည် မည်သို့ကွာခြားသနည်း။ Comparable သည် Object ကိုယ်တိုင်က Compare လုပ်နိုင်သော လုပ်ဆောင်ချက်ကို ပြင်ဆင်ထား၍ ကိုယ်တိုင်က Compare လုပ်ပြီး၊ Comparator သည် အခြားသော ကလပ်စ်တစ်ခုက Compare လုပ်လိုသော Object များအား Compare လုပ်စေပါသည်။


Shuffling


Collections ကလပ်စ်သည် List တစ်ခုအတွင်းရှိ အော့ဘဂျက်များ၏ အစီအစဉ်အား ဖျက်ပေးနိုင်သော shuffle လုပ်ဆောင်ချက်အား ပံ့ပိုးပေးထားပါသည်။ ဤ shuffle လုပ်ဆောင်ချက်သည် gameပရိုဂရမ်များအား ရေးသားရာတွင်အသုံးများသော လုပ်ဆောင်ချက် တစ်ခုဖြစ်သည်။ အကယ်၍ဖဲချပ်များအား အသုံးပြုသော ဂိမ်းများတွင် ဖဲဝေခါနီး ဖဲဖျက်သည့် အခါမျိုးတွင် shuffle လုပ်ဆောင်ချက်ကို အသုံးပြုနိုင်မည် ဖြစ်ပါသည်။ နောက်တဖန် Test Class များရေးသားရာတွင်လည်း အသုံးဝင်နိုင်မည် ဖြစ်ပါသည်။ Online Game များရေးသားပါက Multi Thread ကို အသုံးပြုလေ့ရှိပြီး သတိပြုရန် လိုအပ်သည်မှာ Collections သည် Thread Safe အနေဖြင့် ဒီဇိုင်းရေးသားထားခြင်း မရှိသောအချက်ပင် ဖြစ်၏။ ထို့ကြောင့် Multi Thread Program များတွင် အသုံးပြုရာတွင် Thread Safe ဖြစ်ရန် ပြုပြင်ရေးသားရန်လိုအပ်ပါသည်။

public static void shuffle(List<?> list)

public static void shuffle(List<?> list, Random rd) 


ShufflingSample1.java
package com.mmju.eja.ep1.collections;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ShufflingSample1 {

 static final Object[][] OBJECTS = { { "Name1", "100.05" },
   { "Name2", "100.00" }, { "Name1", "100.01" },
   { "name1", "100.00" }, { "name3", "100.00" } };

 public static void main(String[] args) {
  List<Data> datas = new ArrayList<>();

  for (Object[] obj : OBJECTS)
   datas.add(new Data((String) obj[0], Double.valueOf((String) obj[1])
     .doubleValue()));

  doOutput("Before Shuffling", datas);
  Collections.shuffle(datas);
  doOutput("After Shuffling", datas);
 }

 static class Data {

  String name;
  double value;

  public Data(String name, double value) {
   this.name = name;
   this.value = value;
  }

  public void doOutput() {
   System.out.println(this.name + " : " + String.valueOf(this.value));
  }
 }

 public static void doOutput(String msg, List<Data> datas) {
  System.out.println("------ " + msg + " START ------");
  for (Data d : datas)
   d.doOutput();
  System.out.println("------ " + msg + " END --------\n");
 }

}


Searching


Sort လုပ်ထားသော Listတစ်ခုအတွင်းမှ Object တစ်ခုအားရှာဖွေလိုသည့် အခါမျိုးတွင် Collections#binarySearch အား အသုံးပြုနိုင်ပါသည်။ အမည်အတိုင်း Arrays ကဲ့သို့ပင် Binary Search Algorithm အား အသုံးပြုထားပါသည်။

public static <T> int binarySearch(List<? extends Comparable< ? super T>> list, T key)

public static <T> int binarySearch(List<T> list, T key, Comparator<? super T> c)

SearchSample.java
ppackage com.mmju.eja.ep1.collections;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class SearchSample {

 static final Object[][] OBJECTS = { { "Name1", "100.05" },
   { "Name2", "100.00" }, { "Name1", "100.01" },
   { "name1", "100.00" }, { "name3", "100.00" } };

 static class Data {

  String name;
  double value;

  public Data(Object[] obj) {
   this.name = (String) obj[0];
   this.value = Double.valueOf((String) obj[1]).doubleValue();
  }
 }

 public static void main(String[] args) {

  List<Data> datas = new ArrayList<>();
  Comparator<Data> comparator = new Comparator<SearchSample.Data>() {

   @Override
   public int compare(Data o1, Data o2) {
    int result = 0;
    if (0 != (result = o1.name.compareTo(o2.name)))
     return result;
    return Double.valueOf(o1.value).compareTo(
      Double.valueOf(o2.value));
   }
  };

  for (Object[] obj : OBJECTS)
   datas.add(new Data(obj));

  Collections.sort(datas, comparator);

  for (int i = 0; i < OBJECTS.length; i++)
   System.out.println("Origin index : "
     + i
     + "\tAfter sorting index : "
     + Collections.binarySearch(datas, new Data(OBJECTS[i]),
       comparator));
 }
}
Collections#binarySearch အား အသုံးပြု၍ ရှာဖွေရန် နမှုနာတစ်ခုအား ရေးသားကြည့်ပါသည်။ binarySearch အား အသုံးပြုရာတွင် Arrays ကဲ့သို့ပင် ကြိုတင်၍ Sort လုပ်ထားရန် လိုအပ်ပါသည်။ ဤနေရာတွင်လည်း Comparable မဟုတ်သော ရိုးရိုး Object List အား အသုံးပြုပါမည်။ ထို့အတွက် Comparator အား Sort လုပ်ရာတွင်၎င်း binarySearch တွင်၎င်းနှစ်ကြိမ် အသုံးပြုရန် လိုအပ်ပါသည်။

ပြီးပါက စာကြောင်း ၄၃တွင် sort လုပ်၍ စာကြောင်း ၄၉တွင် binarySearch အားအသုံးပြု၍ OBJECTS အတွင်းရှိ Object များအား တစ်ခုစီ ရှာဖွေပါသည်။ ဤနည်းအားဖြင့် OBJECTS အတွင်းရှိ Object များသည် Sort လုပ်ပြီးသောအခါ မည်သည့်နေရာသို့ ရောက်ရှိသွားသည်ကို သိရှိနိုင်ပါသည်။

အထက်ပါ ပရိုဂရမ်အား Run လုပ်သောအခါ အောက်ပါအတိုင်း တွေ့ရှိရမည် ဖြစ်ပါသည်။


ဆက်ပါဦးမည်။

ကိုးကား
http://docs.oracle.com/javase/tutorial/collections/algorithms/index.html

လေးစားစွာဖြင့်
မင်းလွင်

September 30, 2012

Arrays

ပြီးခဲ့သော အခန်းဆက်ဖြင့် Collections Framework နှင့် ၎င်းတွင်ပါဝင်သော Interface များ အကြောင်းကို ဖော်ပြခဲ့၏။ ယခု အခန်းတွင် ကိန်းစဉ် (Array) များအား အသုံးချနိုင်သော Utility Class အကြောင်းကို ဖော်ပြသွားပါမည်။


ကိန်းစဉ်များအား အသုံးပြုသော Class

java.util.Arrays သည် ကိန်းစဉ်များအား အသုံးပြုရာတွင် အသုံးဝင်သော လုပ်ဆောင်ချက်များအား စုစည်းထားသော Utility Class တစ်မျိုး ဖြစ်၏။ int, double အစရှိသော Primitive Type ကိန်းစဉ် (Array) များအား အသုံးပြုနိုင်ရန် လုပ်ဆောင်ချက်များကို Overload လုပ်ထားသော်လည်း အခြေခံအားဖြင့် လုပ်ဆောင်ချက် ၅မျိုးကို ပံ့ပိုးထား၏။



ကိန်းစဉ်များအား Sort လုပ်ခြင်း


ကိန်းစဉ်အတွင်းရှိ ကိန်းများအား အကြီးအသေး စီစဉ်ရာတွင် အသုံးပြုပါသည်။

static void sort(Object [] obj)

အခြားသော Parameter များ မပါဝင်ပါက ကြီးရာသို့ စီစဉ်သွားမည်ဖြစ်ပြီး၊ အသုံးပြုသည့် အလဂိုရီဇင်မှာ Quick Sort ဖြစ်၏။

static <T> void sort(T [] t, Comparator<? super T> c)

Comparator အား အသုံးပြုခြင်းအားဖြင့် ကိန်းစဉ်အတွင်းရှိ Object များအား နှစ်သက်သလို ပြောင်းလည်း စီစဉ် (sort) နိုင်ပါသည်။

SortSample_01.java
import java.util.Arrays;
import java.util.Comparator;

public class SortSample_01 {

 public static void main(String[] args) {

  wirte("Before sorting:", DATAS);
  
  Arrays.sort(DATAS, new Comparator<Data>() {
   @Override
   public int compare(Data o1, Data o2) {
    return o2.getAge() - o1.getAge();
   }
  });
  
  wirte("After sorting:", DATAS);
  
 }
 
 static void wirte(String title, Data[] datas) {
  System.out.println(title);
  for(Data d : datas) {
   System.out.println(d.getAge() + " : " + d.getName());
  }
 }
 
 static Data [] DATAS;
 
 static {
  DATAS = new Data[3];
  DATAS[0] = new Data("Mg Mg",21);
  DATAS[1] = new Data("Mg BA",25);
  DATAS[2] = new Data("Mg HLA",20);
 }
 
 static class Data {
  String name;
  int age = 0;
  
  Data(String name, int age) {
   this.name = name;
   this.age = age;
  }
  
  String getName() {
   return this.name;
  }
  
  int getAge() {
   return this.age;
  }
 }
}

အထက်ပါ နမှုနာထဲတွင် Data Object ကိန်းစဉ်အား ၎င်း၏ age ၏ အစီအစဉ်အတိုင်း စီစဉ်စေပါသည်။ စီစဉ်ရာမှာကြီးရာမှ ငယ်ရာသို့ စီစဉ်စေလိုပါသဖြင့် စာကြောင်း ၁၀မှ ၁၅အထိ Comparator ကို အသုံးပြု ရေးသားထားပါတယ်။

ရလာသော ရလဒ်မှာ အောက်ပါအတိုင်း ဖြစ်ပါသည်။

Before sorting:
21 : Mg Mg
25 : Mg BA
20 : Mg HLA
After sorting:
25 : Mg BA
21 : Mg Mg
20 : Mg HLA

တဖန် အောက်ပါအတိုင်း ကိန်းစဉ်အတွင်းရှိ အချက်အလက်များကိုလည်း အစနံပါတ်နှင့် အဆုံးနံပါတ်ကို အသုံးပြုကာ အစိတ်အပိုင်းတစ်ခုတည်းကိုလည်း ပြန်လည်စီစဉ် နိုင်၏။

static void sort(Object[] a, int fromIndex, int toIndex)
static void sort(T[] a, int fromIndex, int toIndex, Comparator c)


Binary Search


ကိန်းစဉ်တစ်ခုအတွင်း အချက်အလက်တစ်ခုအား ရှာဖွေရာတွင် အသုံးပြုနိုင်ပါသည်။ ပဋ္ဌမမြောက် ပါရာမီတာ (Parameter) အတွင်းရှိ အချက်အလက်များအတွင်းမှ key object အား binary search အလဂိုရီဇင်အား အသုံးပြု၍ ရှာဖွေမည်ဖြစ်ပြီး၊ တွေ့ရှိသောအခါ ထို key ၏ နေရာအား ရလဒ်အဖြည် ပြန်ပေးမည် ဖြစ်သည်။ အကယ်၍ မတွေ့ရှိပါက အနှုတ်ကိန်းအား ရလဒ်အဖြစ် ပြန်ပေးမည် ဖြစ်ပါသည်။
static int binarySearch (Object [] a, Object key)
static int binarySearch (Object [] a, int fromIndex, int toIndex, Object key)
sttic <T> int binarySearch(T[] a, T key, Comparator<? super T> c) 
Binary Search အား အသုံးပြုရာတွင် အသုံးပြုသော ကိန်းစဉ်အား ကြိုတင်၍ Sort လုပ်ထားရန် လိုအပ်ပါသည်။ Sort လုပ်ထားခြင်းမရှိပါက ရရှိလာသောအဖြေသည် မှန်ကန်လိမ့်မည်ဟု အာမခံနိုင်မည် မဟုတ်ပေ။

လက်တွေ့စမ်းသပ်ကြည့်ပါမည်။ ဦးစွာ ကိန်း သုညမှ ၉၉၉အထိကို ကိန်းစဉ်အတွင်းသို့ ဖြည့်စွက်ပြီး၊ အစီအစဉ်ဖျက်ပါမည်။ ပြီးလျှင် ကိန်းများအား ရှာဖွေကြည့်ပါမည်။

import java.util.Arrays;
import java.util.Collections;

public class SearchSample {

 public static void main(String[] args) {
  Integer [] array = new Integer[1000];
  
  // add member to array
  for(int i=0; i<array.length; i++) {
   array[i] = i;
  }
  
  // shuffle
  Collections.shuffle(Arrays.asList(array));
  
  for(int i=501; i <= 505; i++) {
   System.out.println("Search Number :  " + i);
   System.out.println(Arrays.binarySearch(array, new Integer(i)));
  }
 }

}
ရလဒ်ကိုကြည့်သောအခါ အောက်ပါအတိုင်း တွေ့ရမည် ဖြစ်ပါသည်။


အမှန်အတိုင်း ဖော်ပြနိုင်ခြင်း မရှိပါသဖြင့် အနုတ်ကိန်းကို ဖော်ပြနေပါသည်။ Shuffle လုပ်သည့်နေရာကို Comment Out လုပ်၍ ပြန် Run ကြည့်ပါမည်။


Shuffleမလုပ်ထားပါသဖြင့် ကိန်းစဉ်အတွင်း အစီအစဉ်အလိုက် တည်ရှိနေသောကြောင့်၊ မှန်ကန်စွာ ဖော်ပြပေးနိုင်စွမ်း ရှိကြောင်းကို တွေ့ရပါသည်။

Arrays ရဲ့ အသုံးဝင်သော နောက်လုပ်ဆောင်ချက် တစ်ခုမှာ Array#asList ဖြစ်သည်။ အထက်ပါ နမှုနာထဲတွင် ရေးသားပြီး ဖြစ်သည်။ ကိန်းစဉ်တစ်ခုမှ List ကို ရရှိစေနိုင်သော လုပ်ဆောင်ချက်ဖြည်ပါသည်။


အခြား အသုံးဝင် လုပ်ဆောင်ချက်များ

static void fill(Object[] a, Object val)
static void fill(Object[] a, int fromindex, int toindex, Object val)

Arrays#fill လုပ်ဆောင်ချက်သည် ကိန်းစဉ်အတွင်းရှိ အချက်အလက်များအား val ၏ တန်ဖိုးဖြင့် အစားထိုးနိုင်မည် ဖြစ်ပါသည်။ တဖန် int fromindex, int toindex ပါရာမီတာများ ပါဝင်သည့် လုပ်ဆောင်ချက်ကို အသုံးပြုပါက ကိန်းစဉ်အတွင်းရှိ အချက်အလက်များအား နေရာသတ်မှတ်၍ အစားထိုးနိုင်မည် ဖြစ်ပါသည်။
static boolean equals(Object[] a, Object[] a2)

ကိန်းစဉ်တစ်ခုနှင့် တစ်ခု တူညီကြောင်းအား စမ်းသပ်ရာတွင် အသုံးပြုနိုင်ပါသည်။ တူညီပါက true ကို ရလဒ်အဖြစ် ရရှိမည်ဖြစ်ပြီး၊ မတူညီပါက false ကို ရရှိမည် ဖြစ်ပါသည်။
static <T> T[] copyOf(T[] original, int newLength)
static <T> T[] copyOfRange(T[] original, int from, int to)

အထက်ပါ copyOf အား အသုံးပြုပါက ကိန်းစဉ်တစ်ခုမှ အရေအတွက်အား သတ်မှတ်၍ ကော်ပီကူနိုင်မည်ဖြစ်ပြီး၊ အရေအတွက်သည် မှုရင်းကိန်းစဉ်ရှိ အရေးအတွက်ထက်နည်းနေပါက ပိုနေသည်များကို ဖြတ်ထုတ်မည်ဖြစ်ပြီး၊ များနေပါက လိုအပ်သည်များကို null ဖြင့် ဖြည့်စွက်၍ ကော်ပီကူးမည် ဖြစ်ပါသည်။

တဖန် copyOfRange အား အသုံးပြုပါက အစနေရာနှင့် အဆုံးနေရာအား သတ်မှတ်၍ ကော်ပီကူးနိုင်မည် ဖြစ်သည်။


ကိုးကား
http://www.techscore.com/tech/Java/JavaSE/Utility/5/
http://docs.oracle.com/javase/6/docs/api/java/util/Arrays.html

လေးစားစွာဖြင့်
မင်းလွင်

September 23, 2012

Map

Map အင်တာဖေစ်သည် Collection Framework တွင်ပါဝင်သော အင်တာဖေစ် တစ်မျိုးဖြစ်ပြီး၊ ၎င်း၏ Object များသည်၊ ကီး (key) နှင့် တန်ဖိုး (value) အား တွဲ၍ သိမ်းဆည်းထားနိုင်ပါသည်။ Map အတွင်းတွင် ကီးတစ်ခု၌ တန်ဖိုး နှစ်ခုအား သိမ်းဆည်း၍ မရနိုင်ပါ။ Map သည် သင်္ချာဘာသာရပ်တွင် ပါဝင်သော Function Abstraction အား ကိုယ်စားပြုထားသော အင်တာဖေစ် တစ်မျိုးဖြစ်ပါသည်။

Map.java
public interface Map<K,V> {

    // Basic operations
    V put(K key, V value);
    V get(Object key);
    V remove(Object key);
    boolean containsKey(Object key);
    boolean containsValue(Object value);
    int size();
    boolean isEmpty();

    // Bulk operations
    void putAll(Map<? extends K, ? extends V> m);
    void clear();

    // Collection Views
    public Set<K> keySet();
    public Collection<V> values();
    public Set<Map.Entry<K,V>> entrySet();

    // Interface for entrySet elements
    public interface Entry {
        K getKey();
        V getValue();
        V setValue(V value);
    }
}

လက်ရှိ Java Platform တွင် General Purpose implementations များမှာ အောက်ပါအတိုင်း ဖြစ်ကြ၏။
  • HashMap
    Hash Table ဖွဲ့စည်းပုံကို အသုံးပြုပါသည်။ Set ၏ General Purpose Implementation များအထဲတွင် Performance ပိုင်းဆိုင်ရာတွင် အကောင်းဆုံး Implementation ဖြစ်ပါသည်။ သို့ရာတွင် Iterator လုပ်တဲ့အခါမှာတော့ အစီအစဉ်အား တိကျမှု့ရှိစေမည်ဟု အာမှခံပေးထားနိုင်စွမ်း မရှိပေ။
  • TreeMap
    Red-Black Tree ဖွဲ့စည်းပုံကို အသုံးပြု၍ Element များအား သိမ်းဆည်းထားပါသည်။ key များအား အစီအစဉ်အလိုက် သိမ်းဆည်းနိုင်မည် ဖြစ်သော်လည်း၊ Performance ပိုင်းဆိုင်ရာတွင် HasnMap ထက် အားနည်းမည် ဖြစ်ပါသည်။
  • LinkedHashMap
    အမည်အတိုင်း Hash Table အား Link List နှင့် ပူးတွဲအသုံးပြု ထားသော Implementation တစ်မျိုး ဖြစ်ပါသည်။ တဖန် Insert လုပ်ထားသော အစီအစဉ်ကိုလည်း စောင့်ထိမ်းပေးနိုင်မည် ဖြစ်သည်။
  • HashTable
    Collections Framework မပေါ်ခင်ကတည်းက တည်ရှိခဲ့သော Class တစ်ခုဖြစ်ပြီး၊ နောက်ပိုင်းတွင် Map Interface အား ပြန်လည်၍ Implement လုပ်ထားပါသည်။


HashTable နှင့် ကွာခြားချက်များ


ယခင် HashTable အား အသုံးပြုဘူးသူ ဖြစ်ပါက Map Interface ၏ အခြေခံ လုပ်ဆောင်ချက်များအား ရင်းနှီးပြီး ဖြစ်ပါလိမ့်မည်။ သို့ရာတွင် HashTable နှင့် ကွာခြားချက်တို့မှာ အခြေခံအားဖြင့် အောက်ပါအတိုင်း အချက်သုံးမျိုး ရှိပါသည်။
  • Map Interface သည် တန်ဖိုးများအား အကြိမ်ကြိမ် အလုပ်လုပ်စေရာတွင် Enumeration Objectအား အသုံးပြုသည့်အစား Collection View အား အသုံးပြုထားပါသည်။
  • Map အား အသုံးပြုခြင်းအားဖြင့် အချက်အလက်များအား အကြိမ်ကြိမ်အသုံးပြုစေရာတွင် Key အပေါ်တွင်၎င်း၊ Value အပေါ်တွင်၎င်း၊ Key-Value အပေါ်တွင်၎င်း အခြေပြု၍ အသုံးပြုနိုင်သည်။ HashTable သည် Key-Value အပေါ်ရှိ Iteration အား ပံ့ပိုးပေးနိုင်ခြင်းမရှိပါ။
  • Map အား အသုံးပြုခြင်း အားဖြင့် Iteration လုပ်နေစဉ်မှာလည်း Entries များအား လုံခြုံစိတ်ချစွာ ဖြတ်ထုတ်နိုင်ပါသည်။ HashTable မှာတော့ ဤကဲ့သို့ပြုလုပ်နိုင်ခြင်း မရှိပါ။
Map တွင် HashTable ၏ အချို့သော အသေးစား အစဉ်မပြေမှု့များကိုလည်း ပြုပြင်ထားပါသည်။ HashTable တွင် HashTable#contains လုပ်ဆောင်ချက်ကို ပိုင်ဆိုင်ပြီး၊ ၎င်းသည် ပါရာမီတာသည် တဖိုးအတွင်းတွင် ပါဝင်ပါက true ကို ရလဒ်အဖြစ် ရရှိမည်ဖြစ်ပြီး၊ သို့မဟုတ်ပါက ရလဒ်သည် false ဖြစ်မည် ဖြစ်သည်။ သို့ရာတွင် အမည်အရ အသုံးပြုသူသည် ပါရာမီတာသိ ကီးများအတွင်းတွင်ပါဝင်ပါက true သို့မဟုတ်ပါက false ကိုပြန်ရမည် ဟု ထင်ကောင်းထင်ပါလိမ့်မည်။ အဘယ်ကြောင့်ဆိုသော် HashTable သည် Key များအား အခြေခံအနေဖြင့် သိမ်းဆည်းလေ့ ရှိသောကြောင့် ဖြစ်သည်။ Map အရောက်တွင် အထက်ပါကဲ့သို့ ရေရာခြင်းမရှိသော အမည်များအား ပြုပြင်ပြီး၊ Map#containsKey နှင့် Map#containsValue ကို အသုံးပြုထားပါသည်။



လုပ်ဆောင်ချက်များ


ရလဒ် အမည် ရှင်းလင်းချက်
V put ပါရာမီတာအဖြစ် ကီးနှင့် တန်ဖိုးကိုရယူမည်ဖြစ်ပြီး၊ရယူထားသော ကီးနှင့် တန်ဖိုးအားပူတွဲ၍ သိမ်းဆည်းထားနိုင်မည် ဖြစ်သည်။
V get ပါရာမီတာ အဖြစ်ကီးအား ရယူမည် ဖြစ်ပြီး၊ ကီးနှင့်တွဲ၍ သိမ်းဆည်းထားသော တန်ဖိုး Object အား ရလဒ်အဖြစ်ပြန်လည် ရရှိမည် ဖြစ်သည်။
V remove ပါရာမီတာ ဖြင့်ရယူထားသော ကီးသည် Entery အနေဖြင့် သိမ်းဆည်းထားပါက ကီးနှင့် တန်ဖိုးအား ဖြတ်ထုတ်နိုင်မည် ဖြစ်သည်။
boolean containsKey ပါရာမီတာကီးသည် ကီးများအတွင်းတွင်ပါဝင်ပါက true အားရရှိမည် ဖြစ်ပြီး၊ သို့မဟုတ်ပါက false အား ရရှိမည် ဖြစ်သည်။
boolean containsValue ပါရာမီတာတန်ဖိုးသည် တန်ဖိုးများအတွင်းတွင်ပါဝင်ပါက true အားရရှိမည် ဖြစ်ပြီး၊ သို့မဟုတ်ပါက false အား ရရှိမည် ဖြစ်သည်။
int size Map အတွင်းတွင်ပါဝင်သော Entry များ၏အရေအတွက်ကို ရရှိမည် ဖြစ်သည်။
boolean isEmpty Map သည် Empty ဖြစ်ပါက true ကို ရရှိမည် ဖြစ်ပြီး၊ သို့မဟုတ်ပါက false ကို ရရှိမည် ဖြစ်သည်။
void putAll ပါရာမီတာ အဖြစ်ရယူထားသော Map တစ်ခုအားလက်ရှိ Map Object အတွင်းသို့ ထည့်သွင်းနိုင်မည် ဖြစ်ပါသည်။
void clear Mapအတွင်းတွင်ရှိသော Entry များအားဖျက်ပြစ်နိုင်မည် ဖြစ်ပါသည်။
Set<K> keySet Map အတွင်းရှိ ကီးများအား Set ပုံစံဖြင့် ရရှိနိုင်မည် ဖြစ်သည်။
Collection<V> values Mapအတွင်းရှိ တန်ဖိုးများအား Collection ပုံစံဖြင့် ရရှိနိုင်မည် ဖြစ်သည်။
Set<Map.Entry<K,V>> entrySet Mapအတွင်းရှိ ကီးနှင့် တန်ဖိုး (Entry) အတွဲအား Set ပုံစံဖြင့် ရရှိမည် ဖြစ်ပါသည်။


နမှုနာ


ကျွှန်တော်တို့ Map အား Java ပရိုဂရမ်များရေးသားရာတွင် အကြိမ်ကြိမ် အသုံးပြုနိုင်မည် ဖြစ်သည်။ Database များအတွင်းရှိ တန်ဖိုးများအား ဆက်သွယ်ရာတွင်၎င်း၊ အပလီကေးရှင်းတစ်ခုနှင့် တစ်ခုကြား အချက်အလက်များကို ဆက်သွယ်ရာတွင်၎င်း၊ Web အပလီကေးရှင်းများဆိုပါက Client ဆီမှ Request လုပ်လာသော အချက်အလက်များအား ရယူရာတွင်၎င်း Map Object အား အသုံးပြုနိုင်မည် ဖြစ်ပါသည်။

Map များအား အသုံးပြုရာတွင် သမရိုးကျ အချက်အလက်များအား သိမ်းဆည်းသော Container အဖြစ်အသုံးပြုရုံမက၊ Collections Framework ၏ သဘောတရားအား နားလည်ပြီး ပံ့ပိုးထားသော အလဂိုရီဇင်များကိုပါ အသုံးပြုနိုင်ကြောင်းကို သိရှိနိုင်ပေသည်။

ကျွှန်တော်တို့ ဤနေရာတွင် HashMap နှင့် TreeMap တို့အား အသုံးပြု၍ ၎င်းတို့၏ ခြားနားချက်များကို လေ့လာကြည့်ပါမည်။

MapSample.java
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

public class MapSample {

 public static void main(String[] args) {
  String [] array = {"1","2","3","11","12","13"};
  Map<String, String> hashMap = new HashMap<>();
  
  for(String s : array) {
   hashMap.put(s, s + "_value"); 
  }
  
  Map<String, String> treeMap = new TreeMap<>(hashMap);

  Map<Integer, String> treeMap2 = new TreeMap<>();
  Iterator<Entry<String, String>> itr = hashMap.entrySet().iterator();
  while(itr.hasNext()) {
   Entry<String, String> ent = itr.next();
   treeMap2.put(Integer.parseInt(ent.getKey()), ent.getValue());
  }
  
  System.out.println(hashMap);
  System.out.println(treeMap);
  System.out.println(treeMap2);

 }

}
ကျွှန်တော်တို့ ဤနမှုနာတွင် Integer နှင့် String တို့၏ စာစီပုံကို ကြည့်လိုပါသဖြင့်၊ အသုံးပြုမည့် ကိန်းစဉ် array အတွင်းတွင် 1,2,3,11,12,13ကို ပြင်ဆင်ထားပါသည်။ ပြီးလျှင် ထိုကိန်းစဉ်အတွင်းမှ အချက်အလက်များကို တစ်ခုချင်း hashMap အတွင်းသို့ ဖြည့်စွက်ပါသည်။

ပြီးပါက ထို hashMap ဖြင့် treeMap အား ပြုလုပ်ပါသည်။ နောက်ဆုံးတွင် HashMap အတွင်းမှ Entry များအား ထုတ်၍ ကီးအား Integer ပုံစံပြောင်းကာ treeMap2 အတွင်းသို့ ဖြည့်စွက် သိမ်းဆည်းပါသည်။ နောက်ဆုံးတွင် အထက်ပါ hashMap, treeMap နှင့် treeMap2တို့အား ကွန်ဆိုးတွင် ရေးသားနေစေခြင်း သာဖြစ်သည်။


HashMap ကို သုံးထားသော hashMap သည် အစီအစဉ်ကို သိမ်းမထားပါ၊ တဖန် treeMap သည် TreeMap<String, String> ဖြစ်သောကြောင့် String စာစီပုံအတိုင်း ကီးများကို စီစဉ်ပေးကြောင်း တွေ့ရပါသည်။ နောက်ဆုံး treeMap2 ၏ ကီးမှာ Integer ဖြစ်သောကြောင့် Integer အစီအစဉ်အတိုင်း ကီးများအား 1,2,3,11,12,13 ဟု စီပေးနိုင်ကြောင်းကို တွေ့ရမည်ဖြစ်သည်။

ကျွှန်တော်သည် Easy Java API ခေါင်းစဉ်ဖြင့် Collections Framework အကြောင်းကို မိတ်ဆက်ခဲ့ပါသည်။ Collections Framework နှင့် ၎င်းတွင်ပါဝင်သော Interface များအကြောင်း၊ General Purpose Implementation ကလပ်စ်များကို နမှုနာများအား ရေးသားပြီးဖော်ပြခဲ့ပြီးဖြစ်၏။ Collections Framework နဲ့ ပတ်သက်ပြီး ဤနေရာတွင် ရပ်နားမည် ဖြစ်ပြီး၊ အခြားသော အသုံးဝင်သည့် API များကိုလည်း ဤခေါင်းစဉ် အောက်တွင် ဆက်လက် ဖော်ပြသွားပါဦးမည်။

ကိုးကား

http://docs.oracle.com/javase/tutorial/collections/interfaces/map.html

လေးစားစွာဖြင့်
မင်းလွင်

August 19, 2012

Queue Interface

Queue ဆိုသည်မှာ Collection တစ်မျိုးဖြစ်ပြီး၊ ပါဝင်သော Element များအတွင်းမှ မည်သည့် Element အား ဦးစားပေး အသုံးပြုမည်ဆိုသည်ကို ရွေးချယ် သတ်မှတ်နိုင်ပါသည်။ Collection တွင်ပါဝင်သော လုပ်ဆောင်မှု့များ အပြင် Queue တွင် ပါဝင်သော Element များအပေါ်၊ သွင်းခြင်း၊ ထုတ်ခြင်း နှင့် စစ်ဆေးခြင်း အစရှိသည့် လုပ်ဆောင်ချက်များကို ဖြည့်စွက်ထားပါသည်။

Queue.java
public interface Queue<E> extends Collection<E> {
    E element();
    boolean offer(E e);
    E peek();
    E poll();
    E remove();
}
Queue ၏ လုပ်ဆောင်ချက်များသည် များသောအား ဖြင့် ပုံစံ ၂ခု ပံ့ပိုးထားသည်က များ၏။
  1. လုပ်ဆောင်ချက်အား လုပ်ဆောင်၍ မအောင်မြင်သော အခါ Exception အား Throw လုပ်သည့် ပုံစံ။
  2.  လုပ်ဆောင်ချက်အား လုပ်ဆောင်၍ မအောင်မြင်သော အခါသတ်မှတ်ထားသော တန်ဖိုးတစ်ခုအား (null, false ဒါမှမဟုတ် တစ်ခုခု) return ပြန်လုပ်သည့် ပုံစံ
Queue Interface Structure
Type of Operation Throws exception Returns special value
Insert add(e) offer(e)
Remove remove() poll()
Examine element() peek()

Queue များသည် များသောအားဖြင့် ၎င်း၏ Element များအား FIFO (First-In-First-Out) စီနည်းကို အသုံးပြု၍ စီစဉ်ထား၏။ သို့ရာတွင် Priority Queue ကဲ့သို့ အချို့သော Queue များမှာမူ၊ Element ရဲ့ တန်ဖိုးအပေါ်မှုတည်ပြီး Order လုပ်လေ့ရှိ၏။ သို့ရာတွင် မည်သည့် Queue မဆို ၎င်းတို့၏ Element များ၏ ဦးတည်ရာသည် Queue#remove နှင့် Queue#pull အား ခေါ်ဆိုမည့် ဘက်သို့ ဦးတည်ထားကြပါသည်။ FIFO Queue တစ်ခုမှာတော့ အသစ် Insert လုပ်သည့် Element များအား Order ၏ နောက်ဆုံးတွင် ဖြည့်စွက်ပါသည်။ အခြားသော Queue များဆိုပါက ၎င်းတို့ ကိုယ်ပိုင် သတ်မှတ်ချက် နည်းလမ်းများဖြင့် နေရာချထား လေ့ရှိ၏။ ထို့ကြောင့် Queue Implementations များဟာ Ordering Properties များအပေါ်မှုတည်၍ ကန့်သန့် ရေးသားသင့် ပေသည်။

တဖန် Implementation များတွင် ပါဝင်သော Element အရေအတွက်အား ကန့်သတ်နိုင်ပါသေးသည်။ ဤကဲ့သို့ ကန့်သတ်ထားသော Queue များအား Bounded ဟု ခေါ်ဆိုလေ့ရှိ၏။ java.concurrent Package အောက်တွင် ပါဝင်သော Queue များမှာ Bounded များဖြစ်ကြပြီး၊ java.util Package အောက်ရှိ Queue Implementation များမှာ Bounded များ မဟုတ်ကြပါ။

Collection Interface မှ အမွေးဆက်ခံထားသော add လုပ်ဆောင်ကို အသုံးပြု၍ Queue ၏ အရေအတွက် ကန့်သတ်ချက် ကျော်လွန်၍ Element များအား Insert လုပ်ပါက IllegalStatteException အား Throw လုပ်မည်ဖြစ်သည်။ အကယ်၍ အဆိုပါ အနေအထားမျိုးတွင် Queue#offer အား အသုံးပြုပါက Insert လုပ်၍မရကြောင်း false အား return လုပ်ခြင်း ဖြင့် အသိပေးမည် ဖြစ်ပါသည်။

Queue#remove နှင့် poll သည်လည်း Collection အတွင်းရှင် ဦးဆုံး Element အား ဖျက်ထုတ်ပြစ်ပြီး၊ ၎င်းအား return လုပ်မည် ဖြစ်သည်။ ကွာခြားသည်မှာ Collection အတွင်း Element က မရှိတော့သော အခါ ဖြစ်သည်။ ထိုအခါမျိုးတွင် remove အား ခေါ်ဆိုပါက NoSuchElementException အား throw လုပ်မည် ဖြစ်ပြီး၊ poll အား ခေါ်ဆိုပါက null အား return လုပ်မည် ဖြစ်ပါသည်။

Queue#element နှင့် peekသည်လည်း Headနေရာတွင်ရှိသော Element အား ပြန်ပေးမည် ဖြစ်သော်လည်း ဖျက်ထုတ်ပြစ်ခြင်း မရှိပါ။ Collection အတွင်း Elementမရှိသောအခါ element သည် NoSuchElementException အား throw လုပ်မည် ဖြစ်ပြီး၊ peek အား ခေါ်ဆိုပါက null အား return လုပ်မည် ဖြစ်ပါသည်။

များသောအားဖြင့် Queue များသည် Null အား add လုပ်၍မရပေ။ သို့ရာတွင် ခြွင်းချက်အနေဖြင့် LinkedList Implementation များသည် Null အား add လုပ်၍ရပါသည်။ poll နှင့် peek များသည် null အား အဓိပ္ပါယ်တစ်မျိုး အနေဖြင့်အသုံးပြု နေပါသဖြင့် ဤထူးခြားချက်အား အသုံးမပြုသင့်ပေ။


General Purpose Implementations

  • LinkedList
    LinkedList သည် Queue အင်တာဖေစ်အား Implement လုပ်ထားသော General Purpose Implementation Class တစ်မျိုးဖြစ်ပြီး၊ FIFO (First-In-First-Out) Queue Ordering အား အသုံးပြုထား၏။
  • PriorityQueue
    PriorityQueue သည် Heap Data Structure ပုံစံအား အသုံးပြုထားသော Queue ရဲ့ General Purpose Implementation တစ်မျိုးဖြစ်၏။ Heap Data Structure ဆိုသည်မှာ Tree Data Structure ပုံစံရှိပြီး၊ Parent Node ဟာ Child Node ထက် တူရင်တူ၊ မတူရင်ပို၍ ကြီးရမည် ဟူသော သတ်မှတ်ချက်ရှိပါသည်။
Queue ရဲ့ သဘောသဘာဝအား တည်းခေါက်မိစေရန် Count Down လုပ်သည့် နမှုနာ ပရိုဂရမ်တစ်ခုကို ရေးကြည့်ပါမည်။ ပရိုဂရမ်မှ Argument အနေဖြင့် Count Down လုပ်မည့် ကိန်းတစ်ခုကို ရယူပြီး၊ အဲ့ဒီကိန်းမှစကာ နောက်ဆုံး သုညဖြစ်သည် အထိ FIFO Queue ထဲသို့ ထည့်သိမ်းထားပါမည်။ ပြီးပါက တစ်စက္ကန့် တစ်ခါ Queue ထဲမှ ထုတ်ပြီး ရေတွက်သွားပါမည်။

CountDown.java
import java.util.LinkedList;
import java.util.Queue;

public class CountDown {

 public static void main(String[] args) throws InterruptedException {
  if(args.length < 1)
   System.err.println("Please set the time to count!");

  Queue<Integer> que = new LinkedList<>();
  for(int i=Integer.parseInt(args[0]); i > 0; i--)
   que.offer(i);
  
  while(!que.isEmpty()) {
   System.out.println(que.poll());
   Thread.sleep(1000);
  }
 }

}
ကွန်ပိုင်းလုပ်၍ အလုပ်ခိုင်းကြည့်သော အခါ အောက်ပါအတိုင်း အလုပ်လုပ်နိုင်သည်ကို တွေ့ရပါမည်။


ဆက်ပါဦးမည်။ လေးစားစွာဖြင့်။
မင်းလွင်

August 15, 2012

List Interface

Easy Java API အခန်းဆက်ကို ရေးသားလာခဲ့သည်မှာ ၄ ခန်းမြောက်ကို ရောက်ရှိခဲ့ပြီ ဖြစ်၏။ အစဦးဆုံးတွင် Collection Framework အကြောင်း၊ ဒုတိယ အခန်းဖြင့် Collection Interface အကြောင်း၊ ပြီးခဲ့တဲ့ တစ်ခေါက်ကတော့ Set Interface အကြောင်းကို ဖော်ပြခဲ့၏။ ယခုတစ်ခေါက်တွင်လည်း Collection Framework ၏ အခြေခံ Interface တစ်ခု ဖြစ်သော List Interface အကြောင်းကို ဖော်ပြသွားပါဦးမည်။


List Interface

List Interface သည် Collection Interface ၏ Sub Interface တစ်ခု ဖြစ်ပြီး၊ Element များရဲ့ အစီအစဉ်ကို သိမ်းဆည်း ဖော်ပြပေးနိုင်မှာ ဖြစ်ပြီး Sequence လို့လည်း ခေါ်ဆိုလေ့ရှိ၏။ Set Interface နဲ့ မတူပဲ List Interface ဟာ Duplicate Element များကိုလည်း သိမ်းဆည်းထားနိုင်မှာ ဖြစ်ပါတယ်။ Collection Interface ရဲ့ လုပ်ဆောင်ချက်များအပြင် ပါဝင်သော လုပ်ဆောင်ချက်များမှာ အောက်ပါအတိုင်းဖြစ်၏။

List.java
public interface List<E> extends Collection<E> {
    // Positional access
    E get(int index);
    // optional
    E set(int index, E element);
    // optional
    boolean add(E element); 
    // optional
    void add(int index, E element);
    // optional
    E remove(int index);
    // optional
    boolean addAll(int index, Collection<? extends E> c);

    // Search
    int indexOf(Object o);
    int lastIndexOf(Object o);

    // Iteration
    ListIterator<E> listIterator();
    ListIterator<E> listIterator(int index);

    // Range-view
    List<E> subList(int from, int to);
}
  • Positional Access
    လစ်အတွင်းတွင်ပါဝင်သော Element များအား အစီအစဉ် နံပါတ်ဖြင့် ဆက်သွယ်နိုင်သော လုပ်ဆောင်ချက်များ
  • Search
    လစ်အတွင်းတွင်ပါဝင်သော Object ဖြင့် ၎င်း၏ အစီအစဉ် နံပါတ်အား သိရှိစေနိုင်သော လုပ်ဆောင်ချက်များ
  • Iteration
    Iterator အဖြစ် ပြောင်းလည်း အသုံးပြုနိုင်သော လုပ်ဆောင်ချက်များ
  • Range-View
    လစ်အတွင်းရှိ Element များအား အစနံပါတ်နှင့် အဆုံးနံပါတ်ကိုပေးကာ အပိုင်းပိုင်းဖြတ် ရယူနိုင်သော လုပ်ဆောင်ချက်များ


Implementation Classများ

Java Platform တွင် List အား Implement လုပ်ထားသော General Purpose Implementation Class နှစ်မျိုးရှိပြီး၊ ၎င်းတို့မှာ ArrayList နှင့် LinkedList တို့ပဲ ဖြစ်ကြ၏။ ArrayList သည် Performance ဘက်တွင် ကောင်းမွန်သောကြောင့် အသုံးများပြီး၊ LinkedList ဟာလည်း အချို့သော နေရာများတွင် Performance ပိုမို ကောင်းမွန်၏။ ထို့အပြင် ယခင်ရှိခဲ့ပြီး ဖြစ်သော Vector Class သည်လည်း List Interface အား Implement လုပ်လာခဲ့၏။


Vector နှင့် နှိုင်းယှဉ်ခြင်း

အကယ်၍ Vector ကလပ်စ်အား ယခင်က အသုံးပြုခဲ့ဘူးပါက၊ List Interface ၏ အခြေခံ အသုံးပြုပုံများအား ရင်းနှီးပြီး ဖြစ်ပါလိမ့်မည်။ List သည် Vector ၏ မိုင်နာ လိုအပ်ချက် အချို့ကို ပြုပြင်ထားခြင်းဖြစ်၏။ Vector၏ အသုံးများသော လုပ်ဆောင်ချက်များ ဖြစ်ကြသည့် setElementAt နှင့် elementAt များအား၊ ပို၍တိုသော အမည် ဖြင့် ပြောင်းလည်းထားသည်ကို တွေ့ရ၏။ ပရိုဂရမ် ရေးသည့်အခါတွင် မလိုအပ်ပဲ ရှည်လျားနေခြင်းထက်၊ လိုရင်းတိုရှင်းက ပို၍နားလည်လွယ်မည် ဖြစ်ပေသည်။

// Array ဖြင့်ရေးသားထားခြင်း
a[i] = a[j].times(a[k]);

// Vector ကို သုံးမည်ဆိုပါက
v.setElementAt(v.elementAt(j).times(v.elementAt(k)), i);

// List အား အသုံးပြုခြင်း
l.set(i, l.get(j).times(l.get(k)));
Vector အား အသုံးပြုသည်နှင့် စာလျှင် List အား အသုံးပြုသည်က ပို၍ ရှင်းလင်းသည်ကို တွေ့ရမည် ဖြစ်သည်။

ထို့အပြင် ကော်လက်ရှင်၏ အစိတ်အပိုင်းတစ်ခုကို ဖော်ပြပေးသော လုပ်ဆောင်ချက်ဘက်မှာလည်း Vector ၏ indextOf, lasIndexOf နှင့် setSize လုပ်ဆောင်ချက် ၃ခုအား subList လုပ်ဆောင်ချက်ဖြင့် အစားထိုး ထားပါသည်။


ArrayList နှင့် LinkedList

အတော်များများ Java ပရိုဂရမ်မာများသည် List ၏ Implementation Class အား အသုံးပြုရာတွင် ArrayList အား အသုံးပြုသည်က များကြပါသည်။ အကြောင်း တစ်ခုတွင် ArrayList သည် များသောအားဖြင့် Performance ပိုင်းဆိုင်ရာတွင် ကောင်းမွန်သည်မှာ မှန်၏။ ထိုအထဲတွင် ArrayList ကို အသုံးများသောကြောင့်၊ LinkList အား မသိသောကြောင့် အစရှိသည့် အကြောင်းပြချက်များလည်း ရှိကြမည်ဖြစ်သည်။

ဒီလိုဆိုရင် ArrayList နှင့် LinkedList သည် မည်သို့ကွာခြားမည်နည်း။ အမည်အရ ArrayList သည် Data ဖွဲ့စည်းပုံအား Array အားအသုံးပြု၍၊ Array ၏ Size အား Dynamically တိုးပေးနိုင်စွမ်းရှိ၏။



တဖက် LinkList သည် Data ဖွဲ့စည်းပုံအား Linked List ဖွဲ့စည်းပုံအပေါ် အခြေခံထား၏။ Link List Data ဖွဲ့စည်းပုံဆိုသည်မှာ Data အစုအစည်းအား အစဉ်လိုက်သက်မှတ်ထားပြီး၊ Data တစ်ခုမှ မိမိ၏ နောက်တွင်ရှိသော Data တစ်ခုအား Reference လုပ်နိုင်ရန် စီစဉ်ထားသော ဖွဲ့စည်းပုံမျိုး ဖြစ်၏။

Linked List Structure
ဤကဲ့သို့ အခြေခံ ဖွဲ့စည်းပုံမှာ မတူညီသောကြောင့်၊ အားနည်းချက် အားသာချက်များမှာလည်း မတူညီနိုင်ပေ။
  • ArrayList ဟာ Array ပုံစံကို အခြေခံထားပါသဖြင့် index တစ်ခုဖြင့် အချက်အလက်များအား ရှာဖွေတဲ့ နေရာမှာ ထူးချွံပါတယ်။ နံပါတ်တစ်ခုပေးပြီး လစ်ထဲမှ အချက်အလက်များကို ရယူတဲ့အခါမျိုးမှာ ArrayList ရဲ့  Performance ဟာ ကောင်းမွန်၏။
  • သို့ရာတွင် List အတွင်းသို့ Add လုပ်သည့်အခါတွင် Array ဖြစ်သောကြောင့်၊ Size ကို ပြန်စီစဉ်ရခြင်း အစရှိသည်တို့ကို လုပ်ဆောင်ရန်လိုအပ်ပါသဖြင့်၊ LinkList က ပို၍ ထူးချွံပါသည်။
  • အလားတူစွာပင် remove လုပ်သည့်အခါတွင်လည်း LinkList က reference ကို ပြုပြင်ရုံသာဖြစ်သဖြင့်၊ ArrayList ထက်ပို၍ Performance ကောင်းပါသည်။
  • Memory အသုံးဘက်က ကြီးမည်ဆိုပါက Index များဖြင့်သာ သတ်မှတ်ထားသော ArrayList သည်၊ တစ်ခုချင်း Reference လုပ်သိမ်းနေရပြီး Overhead များနေတတ်သော LinkList ထက်စာလျှင် ပိုမို သက်သာပါသည်။
အထက်ပါ အားနည်းချက်၊ အားသာချက်များအားကြည့်ခြင်းဖြင့် LinkList အား မည်သည့်အခါမျိုးတွင် သုံးသင့်ကြောင်းကို တွေ့မြင်လာမည် ဖြစ်သည်။


List Algorithms

Collection Framework အတွင်းတွင် List အား အသုံးပြုနိုင်သော အလဂိုရီဇင်များအား Collections ကလပ်စ် မှတဆင့် ပံ့ပိုးထားပါသည်။

အမည် ရှင်းလင်းချက်
sort Merge Sort Algorithm ကို အသုံးပြုထားပြီး၊ လျှင်မြန်စွာ၊ Stable ဖြစ်စွာ Sort လုပ်ပေးနိုင်ပါသည်။
shuffle List အတွင်းရှိ Element များအား အစီအစဉ်အတိအကျမရှိ(Randomly) ပြန်လည် စီစဉ်ပေးနိုင်ပါသည်။
reverse List အတွင်းရှိ Element များ၏ အစီအစဉ်အား ပြောင်းပြန် စီစဉ်ပေးနိုင်ပါသည်။
rotate List အတွင်းရှိ Element များအား သတ်မှတ်ထားသော အကွာအဝေး တစ်ခု အထိ Rotate လုပ်ပေးနိုင်မည် ဖြစ်သည်။
replaceAll List အတွင်းရှိ တန်ဖိုးတစ်ခုနှင့် တူညီသော Element များအား အခြားသော တန်ဖိုးဖြင့် အစားထိုးပေးနိုင်မည် ဖြစ်သည်။
fill List အတွင်းရှိ Element များအား တန်ဖိုးတစ်ခုဖြင့် Override လုပ်နိုင်မည် ဖြစ်သည်။
copy List တစ်ခုအား အခြားသော List တစ်ခု အဖြစ် ကော်ပီကူးပေးနိုင်မည် ဖြစ်သည်။
binarySearch List အတွင်းမှ Element တစ်ခုအား Binary Search Algorithm အား အသုံးပြု၍ ရှာဖွေနိုင်မည် ဖြစ်သည်။
indexOfSublist မှုရင်း List အတွင်းမှ Sub List တစ်ခု၏ အစနေရာအား ရှာဖွေရာတွင် အသုံးပြုနိုင်မည် ဖြစ်သည်။ အစနေရာအား ရှာဖွေမတွေ့ရှိပါက -1 ကို return လုပ်မည် ဖြစ်သည်။
lastIndexOfSublist မှုရင်း List အတွင်းမှ နောက်ဆုံးတွေ့ရမည် ဖြစ်သော Sub List တစ်ခု၏ အစနေရာအား ရှာဖွေရာတွင် အသုံးပြုနိုင်မည် ဖြစ်သည်။ အစနေရာအား ရှာဖွေမတွေ့ရှိပါက -1 ကို return လုပ်မည် ဖြစ်သည်။

ကိုးကား
http://docs.oracle.com/javase/tutorial/collections/interfaces/list.html
http://en.wikipedia.org/wiki/Linked_list
http://javarevisited.blogspot.jp/2012/02/difference-between-linkedlist-vs.html

ဆက်ပါဦးမည်။ လေးစားစွာဖြင့်။
မင်းလွင် 

August 12, 2012

Set Interface

Set အင်တာဖေစ်သည် ကော်လက်ရှင် တစ်မျိုးဖြစ်ပြီး၊ ပါဝင်သော Element များအား အမျိုးတူ Element အား တစ်ခုထက်ပို၍ လက်ခံနိုင်ခြင်း မရှိပါ။ ဥပမာအားဖြင့် Set set အထဲသို့ "Myanmar" ကို အကြိမ်ကြိမ် add လုပ် မည်ဆိုလျှင်လည်း ပြန်လည် ခေါ်ယူသောအခါ "Myanmar" တစ်ခုတည်းကိုသာ ရရှိမည် ဖြစ်ပါသည်။ Set အင်တာဖေစ်သည် သင်္ချာဘာသာရပ်၏ အခြေခံ အတွေးအခေါ်တစ်ခုဖြစ်သော Set အား မော်ဒယ်တစ်ခု အနေဖြင့် ကိုယ်စားပြုထားသော အင်တာဖေစ် ဖြစ်ပါသည်။

Setတွင်ပါဝင်သော လုပ်ဆောင်ချက်များသည် Collection တွင်ပါဝင်သော လုပ်ဆောင်ချက်များနှင့် ထပ်တူဖြစ်ပြီး၊ တားမြစ်ချက်အနေဖြင့် Element တစ်ခုအား ထပ်ခါတလည်းလည်း တည်ရှိနိုင်ခြင်း မရှိစေရန် တားမြစ် ထားပါသည်။ တဖန် Setအင်တာဖေစ်သည် equals နှင့် hashCode လုပ်ဆောင်ချက်နှင့် ပတ်သက်သော စီးကမ်းများကိုလည်း တင်းကျပ်စွာ ချမှတ်ထား၏။ အကဲ၍ မတူညီသော Implements Class များကို အသုံးပြုထားသော Set Instance များ အကြားတွင်ပင် နှိုင်းယှဉ်သောအခါ အဓိပ္ပါယ်ကို ကြည့်၍ နှိုင်းယှဉ်နိုင်ရန် စီမံထားပါသည်။ Set နှစ်ခုအား နှိုင်းယှဉ်ရာတွင် ပါဝင်သော Element များက တူညီပါက ထို Set နှစ်ခုသည် တူညီမည် ဖြစ်ပါသည်။

SetCompare.java
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;

public class SetCompare {

 public static void main(String[] args) {
  
  Set<Integer> set1 = new HashSet<>();
  Set<Integer> set2 = new TreeSet<>();
  
  for(int i=0; i<10; i++) {
   set1.add(i);
   set2.add(i);
  }
  
  System.out.println(set1.hashCode());
  System.out.println(set2.hashCode());
  
  System.out.println(set1.equals(set2));
 }

}
အထက်ပါ နမှုနာ၏ စာကြောင်း ၉နှင့် ၁၀ တွင် Set အော့ဘဂျက် set1 နှင့် set2 တို့အား အသီးသီး HashSet နှင့် TreeSet တို့မှ new လုပ်ပြီး တည်ဆောက်ထားပါသည်။ ထို့နောက်တွင် for ဝါကျကို အသုံးပြုကာ အော့ဘဂျက် နှစ်ခုလုံးတွင် 0 မှ 9 အထိ Integer များအား ထည့်သွင်းပါသည်။ နောက်ဆုံး စာကြောင်း ၂၀ တွင် set1 နှင့် set2 တို့အား နှိုင်းယှဉ်ကြည့်နေပါသည်။ အဖြေမှာ အောက်ပါအတိုင်းဖြစ်ပါသည်။


set1 နှင့် set2 ဟာအသီးသီး HashSet နှင့် TreeSet တို့၏ Instance ဖြစ်သော်လည်း ပါဝင်သော Element များမှာ တူညီသောကြောင့် Hash Code မှာလည်း အတူတူဖြစ်ပြီး၊ equals ၏ ရလဒ်မှာလည်း တူညီကြောင်း တွေ့ရှိနိုင်ပါသည်။


General Implementations

Java Platform တွင် Set အင်တာဖေစ်အား အထွေထွေသုံးအနေဖြင့် ပံ့ပိုးထားသော ကလပ်စ် ၃မျိုးရှိပါသည်။
  • java.util.HashSet
    Element များအား သိမ်းဆည်းရာတွင် Hash Table ဖွဲ့စည်းပုံကို အသုံးပြုပါသည်။ Set ၏ General Purpose Implementation များအထဲတွင် Performance ပိုင်းဆိုင်ရာတွင် အကောင်းဆုံး Implementation ဖြစ်ပါသည်။ သို့ရာတွင် Iterator လုပ်တဲ့အခါမှာတော့ အစီအစဉ်အား တိကျမှု့ရှိစေမည်ဟု အာမှခံပေးထားနိုင်စွမ်း မရှိပေ။
  • java.util.TreeSet
    Red-Black Tree ဖွဲ့စည်းပုံကို အသုံးပြု၍ Element များအား သိမ်းဆည်းထားပါသည်။ Element များ၏ တန်ဖိုးအရ အစီအစဉ်ကို စောင့်တည်နိုင်မည် ဖြစ်သော်လည်း၊ Performance ပိုင်းဆိုင်ရာတွင် HasnSet ထက် အောက်ကျမည် ဖြစ်ပါသည်။
  • java.util.LinkedHashSet
    အမည်အတိုင်း Hash Table အား Link List နှင့် ပူးတွဲအသုံးပြု ထားသော Implementation တစ်မျိုး ဖြစ်ပါသည်။ တဖန် Insert လုပ်ထားသော အစီအစဉ်ကိုလည်း စောင့်ထိမ်းပေးနိုင်မှာ ဖြစ်ပါတယ်။
အသီးသီးရဲ့ ထူးခြားချက်ကို သိရှိနိုင်ရန် နမှုနာ တစ်ခုကို စမ်းသပ်ကြည့်ပါမည်။

SetImplementations.java
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;

public class SetImplementations {

 public static void main(String[] args) {
  
  Set<Integer> hashSet = new HashSet<>();
  Set<Integer> treeSet = new TreeSet<>();
  Set<Integer> linkSet = new LinkedHashSet<>();
  
  for (int i=10; i > 0; i--) {
   hashSet.add(i);
   treeSet.add(i);
   linkSet.add(i);
  }
  
  System.out.println("HashSet       : " + hashSet);
  System.out.println("TreeSet       : " + treeSet);
  System.out.println("LinkedHashSet : " + linkSet);
 }

}
အထက်ပါ နမှုနာတွင် Set ၏ Implementations များဖြစ်ကြသော HashSet, TreeSet နှင့် LinkedHashSet တို့အား အသီးသီး အသုံးပြုထားပါသည်။ အဆိုပါ set Object အသီးသီးတွင် For ဝါကျအား အသုံးပြု၍ 10 မှ 1 အထိ ကိန်းများကို ဖြည့်စွက်စေပါသည်။ နောက်ဆုံးတွင် အသီးသီး Console တွင် ဖော်ပြနေစေခြင်း ဖြစ်၏။ ရလဒ်မှာ အောက်ပါအတိုင်း ဖြစ်ပါသည်။


ဤနေရာတွင် HashSet နှင့် TreeSet တို့မှာ တန်ဖိုးအတိုင်း စီစဉ်ထားသကဲ့သို့မြင်ရ၏။ သို့ရာတွင် HashSet မှာမူ အစီအစဉ်ကို အာမခံထားခြင်း မရှိသောကြောင့် အစီအစဉ်ကို လိုအပ်သောအခါ အသုံးပြုရန် မသင့်တော်ပေ။ တဖန် LinkedHashSet မှာမူ Insert လုပ်ထားသည့် အစီအစဉ် အတိုင်း ဖော်ပြပေးနိုင်သည်ကို တွေ့ရပါသည်။

ဤသည်ကိုကြည့်ခြင်းအားဖြင့်၊ Duplicate မဖြစ်သော အချက်အလက်များအား အသုံးပြုလိုပါက Performance အကောင်းဆုံးဖြစ်သော HashSet အား အသုံးပြုသင့်ပြီး၊ တန်ဖိုးအတိုင်း အစီအစဉ်ကို အသုံးပြုလိုပါက TreeSet ကို အသုံးပြုသင့်ပြီး၊ Insert လုပ်ထားသည့် Order ကို အသုံးပြုလိုပါက LinkedHashSet ကို အသုံးပြုသင့်သည်ကို သိရှိနိုင်ပါသည်။


နမှုနာ ပုဒ်စာ

အောက်ပါစာရင်းမှ ကုန်ပစ္စည်း များအား နာမည်အတိုင်း စီစဉ်ပေးပါ။ တဖန် အမည်တူများအား တစ်ကြိမ်ထပ်ပို၍ ဖော်ပြခြင်း မရှိစေရန် စီမံပါ။

[i phone 4s,pencil,ball pen,pen,book,pencil,note book,book,android,i phone 3,i phone 3s,i phone 4s]

SetSample.java
import java.util.Arrays;
import java.util.Set;
import java.util.TreeSet;

public class SetSample {

 static String DATA_LIST = "i phone 4s,pencil,ball pen,pen,book," +
   "pencil,note book,book,android,i phone 3,i phone 3s,i phone 4s";

 public static void main(String[] args) {
  Set<String> treeSet = new TreeSet<>(Arrays.asList(DATA_LIST.split(",")));
  System.out.println(treeSet);
 }

}
အထက်ပါ ပရိုဂရမ်အား ကွန်ပိုင်းလုပ်၍ အလုပ်ခိုင်းကြည့်ပါက အောက်ပါအတိုင်း အဖြေရရှိမည် ဖြစ်ပါသည်။

[android, ball pen, book, i phone 3, i phone 3s, i phone 4s, note book, pen, pencil]

ဆက်ပါဦးမည်။


ကိုးကား
http://docs.oracle.com/javase/tutorial/collections/interfaces/set.html

လေးစားစွာဖြင့်။
မင်းလွင်

August 11, 2012

Collection Interface

Collection သည် အချက်အလက် အစုအစည်းအား ကိုယ်စားပြုပြီး၊ Collection များအားလုံး၏ အခြေခံ အကျဆုံး လုပ်ဆောင်ချက်များအား စုစည်းထားပါသည်။ Collection Framework အတွင်းရှိ General Implementations များတွင် တူညီသော Collection တစ်ခုအား Argument အဖြစ်ရယူသော Constructor တစ်ခုကို ပိုင်ဆိုင်ပြီး Convention Constructor ဟု ခေါ်ဆို၏။ ထို Constructor သည် Argument အဖြစ်ရယူထားသော မည်သည့် ပုံစံရှိ Collection များမှမဆို ၎င်း၏ Election များအား initialize လုပ်ပြီး Collection အသစ်တစ်ခုကို တည်ဆောက်ပါသည်။ ဤနည်းအားဖြင့် Collection တစ်ခုမှ အခြားသော Collection တစ်ခု အဖြစ်ပြောင်းလည်း ပေးနိုင်ခြင်း ဖြစ်ပါသည်။

CollectionSample.java
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class CollectionSample {
 
 public static void main(String[] args) {
  
  Collection<String> list = new ArrayList<>();
  for(int i=0; i<5; i++)
   list.add(String.valueOf(i));
  
  Set<String> set = new HashSet<>(list);
  
  for(Iterator<String> i = set.iterator(); i.hasNext(); )
   System.out.println(i.next());
 }

}

စာကြောင်း ၁၅တွင် ArrayList အော့ဘဂျက် list အား Set အင်တာဖေစ်၏ အော့ဘဂျက်အဖြစ် ပြောင်းလည်းယူ နိုင်သည်ကို တွေ့ရပါသည်။

Collection Interface တွင် ပါဝင်သော လုပ်ဆောင်ချက်များမှာ အောက်ပါအတိုင်း ဖြစ်ကြ၏။

Collection.java
public interface Collection<E> extends Iterable<E> {
    // Basic operations
    int size();
    boolean isEmpty();
    boolean contains(Object element);
    // optional
    boolean add(E element);
    // optional
    boolean remove(Object element);
    Iterator<E> iterator();

    // Bulk operations
    boolean containsAll(Collection<?> c);
    // optional
    boolean addAll(Collection<? extends E> c); 
    // optional
    boolean removeAll(Collection<?> c);
    // optional
    boolean retainAll(Collection<?> c);
    // optional
    void clear();

    // Array operations
    Object[] toArray();
    <T> T[] toArray(T[] a);
}
ကော်လက်ရှင် အင်တာဖေစ်သည် အချက်အလက် အုပ်စုတစ်စုတွင် ပါဝင်သင့်သော အခြေခံ လုပ်ဆောင်ချက်များဖြင့် ဖွဲ့စည်းထားပါသည်။ Collection Interface ၏ size နှင့် isEmpty လုပ်ဆောင်ချက်ဖြင့် ကော်လက်ရှင်တွင်ပါဝင်သော Element များ၏ ပမာဏကို သိရှိနိုင်ပြီး၊ contains လုပ်ဆောင်ချက်ကို အသုံးပြုပါက Object တစ်ခုသည် Collection အတွင်းတွင် ပါဝင်ခြင်း ရှိမရှိကို သိရှိနိုင်ပါသည်။

Collection အတွင်း Element အား ဖြည့်စွက်ရာတွင် add ကို သော်၎င်း၊ ဖယ်ပြစ်ရာတွင် remove ကို အသုံးပြုနိုင်ပါသည်။ Element များအား တစ်ပြိုင်နက်တည်း အသုံးပြုလိုပါက containsAll၊ addAll၊ removeAll၊ retainAll နှင့် clear လုပ်ဆောင်ချက်များအား အသုံးပြုနိုင်ပါသည်။

ကော်လက်ရှင် အတွင်းရှိ Element များအား အသုံးပြုရန် Forဝါကျအား အသုံးပြုနည်းနှင့် Iterator အားအသုံးပြုနည်း ဟူ၍ နည်းလမ်းနှစ်ခု ရှိပါသည်။

CollectionLoopSample.java
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class CollectionLoopSample {

 public static void main(String[] args) {
  Collection<String> collection = new ArrayList<>();
  collection.add("one");
  collection.add("two");
  collection.add("three");
  
  for(String s : collection)
   System.out.println(s);
  
  Iterator<String> itr = collection.iterator();
  while(itr.hasNext())
   System.out.println(itr.next());
 }

}
စာကြောင်း ၁၃တွင် for(String s : collection) ဟု ရေးသားခြင်းအားဖြင့် Collection အော့ဘဂျက် အတွင်းမှ Element များအား String အော့ဘဂျက် s အဖြစ် တစ်ခုချင်းစီ အသုံးပြုနိုင်မည် ဖြစ်သည်။ တဖန် စာကြောင်း ၁၆ကဲ့သို့ Collection#iterator လုပ်ဆောင်ချက်အား အသုံးပြုခြင်းအားဖြင့် Iterator အော့ဘဂျက်ကို ရရှိမည် ဖြစ်ပြီး၊ while ဝါကျကို အသုံးပြု၍ iterator အတွင်း ရှိသမျှ Element များအား တစ်ခုချင်း ထုတ်ယူ အသုံးပြုနိုင်မည် ဖြစ်သည်။

တဖန် Collection#toArray လုပ်ဆောင်ချက်အား အသုံးပြုပါက Object [] ၏ ကိန်းစဉ် အော့ဘဂျက်ကို ရရှိနိုင်မည် ဖြစ်ပြီး၊ Collection#toArray(T [] a)  အား အသုံးပြုပါက T[] ၏ အော့ဘဂျက်ကို ရရှိမည် ဖြစ်ပါသည်။

Collections Framework

အကယ်၍ စာဖတ်သူသည် Basic Programming နှင့် Easy Java ခေါင်းစဉ်အောက်ရှိ သင်ခန်းစာများအား လေ့လာခဲ့ပါက၊ Java ပရိုဂရမ်မင်း၏ အခြေခံ ရေးသားပုံနှင့် Object Oriented ရဲ့ သဘောတရားများအား နားလည်ခဲ့ပြီ ဖြစ်ပါလိမ့်မည်။ အပြင်လောကနှင့် နှိုင်းယှဉ်မည် ဆိုပါက စကားစတတ်ခါစ ကလေးတစ်ယောက် ဖြစ်ပြီဟု ဆိုရမည် ဖြစ်သည်။ စကား တတ်ပြီ ဖြစ်သော်လည်း စာကားလုံးမကြွယ်သေးပေ။ ရိုးရှင်းသော ပရိုဂရမ် အတိုလေးများအား ရေးနိုင် ဖတ်နိုင်ပြီ ဖြစ်ပါလိမ့်မည်။ ထိုမှတဆင့် စကားလုံးကြွယ်သော လူကြီးတစ်ယောက်ဖြစ်ရန် ဆက်လက်လေ့လာရန် လိုအပ်ပါသေးသည်။

အပလီကေးရှင်းတစ်ခုအား တည်ဆောက်ရာတွင် ဖိုင်အသွင်းအထုတ်များ၊ အချက်အလက်များအား အစဉ်ပြေပြေ အသုံးပြုနိုင်ရန် အတွက် ကော်လက်ရှင်များနှင့် အင်တာနက်နှင့် Thread များအား အသုံးပြုရန် လိုအပ်သည့်အခါများ ရှိလာပါလိမ့်မည်။ ထိုအခါမျိုးတွင် ပရိုဂရမ်မင်းဘာသာရပ် တွင် ပံ့ပိုးပေးထားသော API များအား အသုံးပြု၍သော်၎င်း၊ အကယ်၍ ပံ့ပိုးထားခြင်း မရှိပါက မိမိကိုယ်တိုင်ရေးသား၍သော်၎င်း ပြဿနာများအား ဖြေရှင်းရန် လိုအပ်ခဲ့ပေသည်။

ယနေ့ခေတ် အသုံးများသော ပရိုဂရမ်မင်းဘာသာရပ် အတော်များများသည် အခြေခံ Input / Output နှင့် Data Collection များအပြင် အသုံးဝင်သော API များအား ပြင်ဆင်ထားလေ့ရှိပါသည်။ ထိုအထဲတွင် နှစ်ရှည်လများ Open Source အနေဖြင့် အသုံးများခဲ့သော Java ဘာသာရပ်တွင် အသုံးဝင်သော API များနှင့် Utility Framework များစွာကို Java Run TimeEnvironment အတွင်းတွင် အသင့်ပြင်ဆင်ထားခဲ့ပါသည်။

ကျွှန်တော်တို့ Java ဘာသာရပ်တွင် အချက်အလက်များအား အသုံးပြုရန် ပြင်ဆင်ထားသော Utility Class များမှ တဆင့် လေ့လာသွားပါဦးမည်။ java.util နှင့် java.text package ၏ အောက်တွင် အသုံးများသော ကလပ်စ်နှင့် အင်တာဖေစ်များအား စုစည်း ရေးသားထားလေ့ ရှိပါသည်။ ယခုတစ်ခေါက်တွင် Collection Framework နှင့် ပတ်သက်၍ လေ့လာ ရေးသားသွားပါမည်။


Collection Framework

ပရိုဂရမ်တစ်ခုတွင် အချက်အလက်များအား မည်သည့်ပုံစံဖြင့် အသုံးပြုမည်ဆိုသည့် အချက်သည် လွန်စွာအရေးကြီး လှပါသည်။ Java ပရိုဂရမ်မင်းဘာသာရပ်တွင်လည်း အချက်အလက်များအား အစဉ်ပြေစွာ အသုံးပြုနိုင်ရန် ပုံစံအမျိုးမျိုး ဖြင့် အသုံးပြုလာကြ၏။ ကနဦး Java အား လေ့လာရာတွင် အတွေ့များမည်ဖြစ်သော Vector များမှ အစ Array ဟု ခေါ်သော ကိန်းစဉ်များ၊ အချက်အလက်များအား အစုလိုက်အဝေးလိုက် အသုံးပြုနိုင်သော List များ၊ အမည်နှင့် တန်ဖိုးအား ပူးတွဲထားသော Dictionary ပုံစံများ၊ အစရှိသည့် အော့ဘဂျက်များအား အသုံးပြုလာခဲ့ ကြ၏။

Java 2 ဟု ခေါ်သော Java SE 1.4 အရောက်တွင် Collections Framework ကို စတင် ဖြည့်စွက်လာခဲ့ပါသည်။ Collection ဆိုသည်မှာ အချက်အလက်များအား အစုလိုက် ဖော်ပြ အသုံးပြုနိုင်သော Object များကို ရည်ညွှန်းပါသည်။ Collection Framework ဆိုသည်မှာအချက်အလက်အစုအဝေးအား အသုံးပြုနိုင်သော၊ ထိမ်းသိမ်းနိုင်သော နည်းလမ်းများအား ပေါင်းစုထားသော အာကီတက်ချာ တစ်မျိုးပင် ဖြစ်၏။


အသုံးပြုခြင်း၏ အကျိုးကျေးဇူးများ

Collection Framework အား အသုံးပြုခြင်း အားဖြင့် ရရှိနိုင်သော အကျိုးကျေးဇူးများမှာ အောက်ပါအတိုင်း ဖြစ်၏။
  • ပရိုဂရမ်များအား ရေးသားရာတွင် သက်သာစေခြင်း
    အသုံးပြုနိုင်သော အချက်အလက် ဖွဲ့စည်းပုံနှင့် အလဂိုရီဇင်အား အသင့် ပြင်ဆင်ထားပါသဖြင့် ပရိုဂရမ်များအား အသစ်ထပ်မံ ရေးသားချင်းမှ သက်သာစေနိုင်ပါသည်။
  • Performance အား တိုးတက်စေနိုင်ခြင်း
    Collection Framework တွင် အသုံးပြုနိုင်သော Data ဖွဲ့စည်းပုံနှင့် အဆင့်မြင့် အလဂိုရီဇင်များအား ပံ့ပိုးထားပါသည်။ ထို့အပြင် အင်တာဖေစ်များအား Implement လုပ်ထားသော ကလပ်စ်များသည်လည်း တစ်ခုနှင့် တစ်ခု အပြန်အလှန် ပြောင်းလည်း အသုံးပြုနိုင်ရန် ရည်ရွယ်၍ တည်ဆောက်ထားပါသဖြင့်၊ နှစ်သက်ရာ အလဂိုရီဇင်သုံး ကလပ်စ်များအား ပြောင်းလည်း အသုံးပြုသွားရုံဖြင့် တစ်ဆင့်ထက်တဆင့် Performance တိုးတက်အောင် ရေးသားနိုင်ပါသည်။
  • ပတ်သက်ခြင်းမရှိသော ပရိုဂရမ်များ အကြားတွင် အပြန်အလှန် ဆက်သွယ် အသုံးပြုစေနိုင်ခြင်း
    Collection များအား API များ၏ ကြားခံ အင်တာဖေစ် အနေဖြင့် အသုံးပြုခြင်းအားဖြင့် ဘုံသုံးဘာသာရပ် တစ်ခုကို ဖြစ်တည်စေနိုင်ပါသည်။
  • API အား လေ့လာရန် အချိန်အား သက်သာစေခြင်း
    ဤကဲ့သို့ ကော်လက်ရှင်များအား စုစည်းထားခြင်း အားဖြင့်၊ အသုံးပြုခါနီးမှ လေ့လာရသည့် အချိန်အား သက်သာစေနိုင်ပါသည်။
  • API အား ရေးသားရန် အချိန်အား သက်သာစေခြင်း
    ပြင်ဆင်ထားသော API အား အသုံးပြုခြင်းအားဖြင့်၊ မိမိကိုယ်တိုင် ရေးသားရမည့် အချိန်ကို သက်သာစေနိုင်ပါသည်။
  • ဆော့ဖ်ဝဲများအား ပြန်လည်အသုံးချနိုင်စေရန် အထောက်အကူပြုနိုင်ခြင်း
    ကော်လက်ရှင်နှင့် အလဂိုရီဇင်များ အပြင်၊ ၎င်းတို့အား အသုံးပြုနိုင်သော Utility များအား ပံ့ပိုးထားခြင်း အားဖြင့် ဆော့ဖ်ဝဲများအား ပြန်လည် အသုံးပြုရာတွင် အထောက်အကူပြုစေနိုင်ပါသည်။


ပါဝင်သော အစိတ်အပိုင်းများ

ကော်လက်ရှင် ဖရိမ်ဝက်တွင် ပါဝင်သော အစိတ်အပိုင်းများမှာ အောက်ပါအတိုင်း ဖြစ်ကြပါသည်။
  • ကော်လက်ရှင် အင်တာဖေစ်
    Set, List နှင့် Map အစရှိသော ကော်လက်ရှင်များအား ဆိုလိုခြင်း ဖြစ်ပြီး၊ ကော်လက်ရှင် ဖရိမ်ဝက်သည် အစရှိသည့် အင်တာဖေစ်များအား အခြေခံ၍ဖွဲ့စည်း ထားပါသည်။
  • General Implementations
    ကော်လက်ရှင် အင်တာဖေစ်များအား ပံ့ပိုးထားသော အခြေခံ ကလက်စ်များ ဖြစ်ကြ၏။
  • Legacy Implementations
    Vector နှင့် HashTable များကဲ့သို့ ယခင်က ကော်လက်ရှင်ကလပ်စ်များအား ပြန်လည်ပြုပြင်၍ Collection Interface အား ပံ့ပိုးထားခြင်း ဖြစ်၏။
  • အထူး ပံ့ပိုးမှု့များ (Special Implementations)
    အခြေအနေတစ်ခုအတွက် သီးခြားပံ့ပိုးထားသော ကလပ်စ်များ ဖြစ်ကြ၏။ ၎င်းတို့အား အသုံးပြုခြင်း အားဖြင့် သီးခြားအသုံးပြုပုံ၊ ကန့်သတ်ချက်များနှင့် လုပ်ဆောင်ချက်များအား လုပ်ဆောင်စေနိုင်ပါသည်။
  • Concurrent Implementations
    အပြိုင်အလုပ်လုပ်စေနိုင်သော Concurrent အပလီကေးရှင်းများအတွက် ပံ့ပိုးထားသော ကော်လက်ရှင် ကလပ်စ်များ ဖြစ်ကြ၏။
  • Wrapper Implementations
    ကော်လက်ရှင် အင်တာဖေစ်များအပြင်၊ Synchronization ကဲ့သို့ အခြားသော ဖန်ရှင်များအား အသုံးပြုရန် ပံ့ပိုးထားသော ကလပ်စ်များ ဖြစ်ကြ၏။
  • Convenience Implementations
    Performance မြင့်မားစေရန် ကော်လက်ရှင်ဖရိမ်ဝက်၏ လုပ်ဆောင်ချက်များအား အနည်းဆုံး ပံ့ပိုးထားသော ကလပ်စ်များ ဖြစ်ကြ၏။
  • Abstract Implementations
    အသုံးပြုသူက စိတ်ကြိုက်ပြုပြင် အသုံးပြုနိုင်ရန် ရည်ရွယ်၍၊ ကော်လက်ရှင်အင်တာဖေစ်၏ အချို့သော အခြေခံ လုပ်ဆောင်ချက်များအား ဖြည့်စွက်ရေးသားထားသော Abstract ကလပ်စ်များ ဖြစ်ကြ၏။
  • အလဂိုရီဇင်
    ကော်လက်ရှင် ဖရိမ်ဝက်တွင် လစ်များအား အစီအစဉ်ပြောင်းခြင်း ကဲ့သို့ ကော်လက်ရှင်များအား အမျိုးမျိုးအသုံးပြုနိုင်သော Static Method များလည်း ပါဝင်ပါသည်။
  • Infrastructure
    ကော်လက်ရှင် အင်တာဖေစ်များအား အဓိကထားပံ့ပိုးပေးနိုင်သော အင်တာဖေစ်များဖြင့် ဖွဲ့စည်းထား၏။
  • Array Utilities
    ကနဦးပုံစံ ကိန်းစဉ် (Primitive Type Array) များနှင့် ကိုးကားပုံစံ ကိန်းစဉ် (Reference Type Array) များအား အသုံးချနိုင်သော Utility Function များဖြစ်ကြ၏။ တိတိကျကျဆိုရမည် ဆိုလျှင် ၎င်းတို့သည် Collection Framework ၏ အစိတ်အပိုင်းတစ်ခုဟု ဆိုရန်ခက်ခဲသော်လည်း၊ Collection Framework နှင့် အတူ Java Platform အပေါ်တွင် ဖြည့်စွက်ခဲ့ပြီး၊ Collection Framework က အသုံးပြုသော Infrastructure အပေါ်တွင် မှီခို၍ တည်ဆောက်ထားပါသည်။


Collection Interfaces

Java ဘာသာရပ်တွင် Collection Framework အား Interface များအား အခြေခံ၍ ဖွဲ့စည်း တည်ဆောက် ထားပါသည်။ Collection Framework တွင်ပါဝင်သော အခြေခံ Interface များမှာ အောက်ပါအတိုင်း ဖြစ်ပါသည်။


Collection Framework သည် အခြေခံအားဖြင့် အုပ်စုနှစ်ခုဖြင့် ဖွဲ့စည်းထားပြီး၊ ၎င်းတို့မှာ Collection Interface မှ ဆင်းသက်လာသော အင်တာဖေစ် အုပ်စုနှင့်၊ Map Interface မှ ဆင်းသက်လာသော အုပ်စုတို့ ဖြစ်ကြပါသည်။

Collection အင်တာဖေစ်မှ ဆင်းသက်လာသော အင်တာဖေစ်များမှာ အောက်ပါအတိုင်း ဖြစ်ကြ၏။

Map အင်တာဖေစ်မှ ဆင်းသက်လာသော အင်တာဖေစ်များမှာ အောက်ပါအတိုင်း ဖြစ်ကြ၏။
Collection အင်တာဖေစ်၏ javadoc တွင် လုပ်ဆောင်ချက် ရှင်းလင်းချက်များ၌ (optional operation) ရေးသားထားသည်ကို မကြာခဏ တွေ့ရတတ်ပါသည်။ လိုအပ်မှသာ ပြည့်စွက်ရေးသားရန် လိုသော လုပ်ဆောင်ချက်များ ဖြစ်ကြ၏။ ဖြည့်စွက်ရေးသားထားပုံ အပေါ်မှုတည်၍ အချို့သော လုပ်ဆောင်ချက်များအား ရေးသားထားခြင်း မရှိသည့်အခါများ ရှိတတ်ပါသည်။ ဖြည့်စွက်ရေးသားထားခြင်း မရှိသည့် လုပ်ဆောင်ချက် များအား ခေါ်ယူ အသုံးပြုမိပါက UnsuportedOperationException ကို ဖြစ်ပေါ်စေမည် ဖြစ်သည်။ ထို့ကြောင့် ဖြည့်စွက်ရေးသားထားသော ကလပ်စ်၏ Document (javadoc) များတွင် ပံ့ပိုးပေးထားသော Optional Operation များ အကြောင်းကို ဖော်ပြရန်လိုအပ်ပါသည်။ ဤကဲ့သို့ အသုံးပြုပုံကို နားလည်လွယ်ကူစေရန် အတွက် ဘာသာရပ်ဆိုင်ရာ ဝေါဟာရ အချို့ကို ဖြည့်စွက်ခဲ့၏။
  • ပြုပြင်ပြောင်းလည်းခြင်း ဆိုင်ရာ လုပ်ဆောင်ချက်များ ဖြစ်ကြသော add, remove နှင့် clear အစရှိသည့် လုပ်ဆောင်ချက်များအား ပြုလုပ်နိုင်သော ကော်လက်ရှင်အား unmodifiable ဟု ခေါ်ဆိုပါသည်။ တဖန် modifiable မဟုတ်သော Collection များအား modifiable ဟု ခေါ်ဆို၏။
  • Collection Object အတွင်းရှိ မည်သည့် ပြောင်းလည်းချက်မျိုးမဆို မမြင်နိုင်ဘူးဟု အာမှခံနိုင်သော Collections များအား immutable ဟု ခေါ်ဆို၏။ တဖန် immutable မဟုတ်သော Collection များသည် mutable များ ဖြစ်ကြပါသည်။
  • List Object တစ်ခု အတွင်းရှိ Object များအား ပြောင်းလည်းနိုင်သော်လည်း Object များ၏ အရေအတွက်ကို ပြောင်းလည်းနိုင်ခြင်း မရှိသော List များအား fixed-size ဟု ခေါ်ဆိုပါသည်။ တဖန် fixed-size မဟုတ်သော List များအား variable-size ဟု ခေါ်ဆိုပါသည်။
  • Index များဖြင့် ဆက်သွယ်ထားသော Element များအား လျှင်မြန်စွာ (သတ်မှတ်ထားသော အတိုင်းအတာတစ်ခု အတွင်း) ဆက်သွယ်နိုင်သော List များအား random access list ဟု ခေါ်ဆို၏။ တဖန် index လုပ်ထားသော Element များ အဖြစ် အသုံးပြုခြင်း မရှိသော List များအား sequential list ဟု ခေါ်ပါသည်။ List တစ်ခုသည် Random access လားဟု သိရှိစေနိုင်သည်မှာ RandomAccess Marker အင်တာဖေစ် ပင်ဖြစ်၏။ ထိုကဲ့သို့ မိမိ အသုံးပြုနေသော List သည် Random Access လား Sequential Access လားဟု ခွဲခြားသိရှိခြင်းအားဖြင့် သဘောသဘာဝ အပေါ်မှုတည်၍ အခြေခံ အလဂိုရီဇင်များအား ပြုလည်းစေနိုင်ပြီး၊ Performance အား တိုးတက်စေရန် စီမံနိုင်မည် ဖြစ်သည်။


ကော်လက်ရှင်များအား ပံ့ပိုးခြင်း


ကော်လက်ရှင် ဖရိမ်ဝက်တွင် ကော်လက်ရှင် အင်တာဖေစ်များအား အပြင်၊ ၎င်းတို့အား ပံ့ပိုးထားသော ကလပ်စ်များလည်း ပါဝင်၏။ General Implementations များတွင် ပါဝင်သော ကလပ်စ်များအား ၎င်းတို့၏ အမည်ကို ကြည့်ခြင်းအားဖြင့် မည်သို့အသုံးပြုနိုင်သည်ကို သိရှိနိုင်မည် ဖြစ်သည်။ General Implementations ရှိ ကလပ်စ်များ၏ အမည်မှာ များသောအားဖြင့် <Implementation-style><Interface> ဟု ရေးသားလေ့ ရှိသောကြောင့် ဖြစ်၏။ General Implementations တွင် ပါဝင်သော ကလပ်စ်များမှာ အောက်ပါအတိုင်း ဖြစ်၏။

Interface Hash Table Resizable Array Balanced Tree Linked List Hash Table + Linked List
Set HashSet TreeSet LinkedHashSet
List ArrayList LinkedList
Deque ArrayDeque LinkedList
Map HashMap TreeMap LinkedHashMap

အထက်ပါ ကလပ်စ်များသည် optional operations များအားလည်း ပံ့ပိုးပေးထားပြီး၊ အသုံးပြုနိုင်သော Element များအပေါ်တွင်လည်း သက်မှတ်ချက်၊ တားဆီးချက်များမရှိပါ။ တဖန် ၎င်းတို့သည် unsynchronized များဖြစ်ကြ၏။ သို့ရာတွင် Collection Framework တွင်ပါဝင်သော static factory ၏ synchronization wrappers အား အသုံးပြုခြင်းအားဖြင့် unsynchronized collection များအား synchronied ဖြစ်အောင် ပြုလုပ်ပေးနိုင်၏။ Implementations အသစ်များအားလုံးတွင် fail-fast iterators ကို အသုံးပြုထားပြီး၊ ၎င်းသည် ပြိုင်တူပြောင်းလည်းချက်များအား ပြုလုပ်သည်ကို သိရှိနိုင်ပြီး၊ လျှင်မြန်သပ်ရပ်စွာ အမှားကို ဖော်ပြပေးနိုင်၏။ မလိုလားအပ်သော လုပ်ဆောင်ချက် အမှားများအား ဖြစ်ပေါ်စေခြင်း ရှိနိုင်မည် မဟုတ်ပေ။

AbstractCollection, AbstractSet, AbstractList, AbstractSequentialList နှင့် AbstractMap ကလပ်စ်များသည် အဓိက အင်တာဖေစ်များ၏ အခြေခံလုပ်ဆောင်ချက်များအား ပံ့ပိုးထားပြီး၊ ဖြည့်စွက်ရေးသားသူကို ၎င်းတို့အား ထပ်မံရေးသားခြင်းမှ သက်သာစေနိုင်ပါသည်။ ၎င်းကလပ်စ် များ၏ Documents များတွင်မည်သည့် လုပ်ဆောင်ချက်များအား ပံ့ပိုးထားပြီးဖြစ်ပြီး၊ မည်သည့် လုပ်ဆောင်ချက်များအား ဖြည့်စွက်ရေးသားရန် လိုသည် ဆိုသည်ကို လွယ်ကူစွာ သိရှိနိုင်ပါသည်။ ဤကဲ့သို့ အခြေခံ လုပ်ဆောင်ချက်များအား ရေးသားပြီး ဖြစ်သော Abstract Class များအားဖြည့်စွက်ရေးသား ခြင်းအားဖြင့်၊ မိမိရေးသားသော သီခြားကလပ်စ် များ၏ အခြေခံလုပ်ဆောင်ချက် Performance ကို တိုးမြင့်စေနိုင်ပါသည်။


ကိုးကား
http://docs.oracle.com/javase/7/docs/technotes/guides/collections/overview.html


ဆက်ပါဦးမည်။ လေးစားစွာဖြင့်။
မင်းလွင်