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

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

No comments:

Post a Comment