.::. Hendra Jaya .::.

July 2, 2009

Geometric Programming

Filed under: Java — hjaya @ 8:10 am

Dalam post kali ini, kita akan membahas tentang Geometric Programming yang sederhana-sederhana aja.

  1. Sebagai permulaan, kita akan (amat) sangat membutuhkan kelas Point2D (titik). Kelas Point2D kita rancang sebagai berikut:

    public final class Point2D implements Serializable, Comparable<Point2D>{
        private static final long serialVersionUID = -6165181156932437469L;
        final Double x;
        final Double y;

        public Point2D(final double x, final double y){
            this.x = x;
            this.y = y;
        }

        public Double getX() {return x;}
        public Double getY() {return y;}

        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((x == null) ? 0 : x.hashCode());
            result = prime * result + ((y == null) ? 0 : y.hashCode());
            return result;
        }

        public boolean equals(Object obj) {
            if (this == obj) return true;
            if (obj == null) return false;
            if (getClass() != obj.getClass()) return false;
            
            final Point2D other = (Point2D) obj;
            if (x == null) {
                if (other.x != null) return false;
            }
            else if (!x.equals(other.x)) return false;
            
            if (y == null) {
                if (other.y != null) return false;
            }
            else if (!y.equals(other.y)) return false;
            
            return true;
        }

        public int compareTo(Point2D p) {return x.compareTo(p.x) == 0 ? (y.compareTo(p.y)) : (x.compareTo(p.x));}

        public String toString(){return x + "," + y;}

  2. Kemudian kita akan membutuhkan kelas Points yang akan melakukan operasi-operasi geometrik: Letakkan kelas Points pada package yang sama dengan kelas Point2D dan Point3D.

    public final class Points {
        public static double calcPolygonArea(Point2D[] points){
            assert(points.length > 2);
           
            double result = 0D;
            for (int i = 1; i <= points.length; i++)
                result += points[i % points.length].x * (points[(i+1) % points.length].y - points[i-1].y);
            return Math.abs(result) / 2;
        }

        public static double calcDistanceBetweenTwoPoints(Point2D p1, Point2D p2){
            return Math.hypot(p1.x - p2.x, p1.y - p2.y);
        }

June 23, 2009

Quiz : Tampilkan Kata Demi Kata

Filed under: Java — hjaya @ 2:48 pm

Dengan hanya menggunakan

  1. Method indexOf(int) pada String atau overload-nya
  2. Method substring(int) pada String atau overload-nya…
  3. Satu dan hanya satu kali iterasi, yaitu via while(boolean);

Tampilkan sebuah string kata per kata.

Contoh :

public class TampilPerKata {
  public static void main(String[] args) {
    String kalimat = "mari kita pergi berlibur";
    while (/*code*/) {
      /*code*/
    }
  }
}


Dan output yang dihasilkan adalah :
mari
kita
pergi
berlibur

Catatan : String yang diberikan pasti dalam format yang benar, sehingga tidak perlu validasi lanjut.

Dan inilah jawaban terbaik yang bisa saya berikan :

public class TampilPerKata {
  public static void main(String... args){
    String kalimat = "mari kita pergi berlibur";

    boolean lanjut = true;
    while (lanjut){
      int i = kalimat.indexOf(" ");
      lanjut = i != -1;
      System.out.println(lanjut ? kalimat.substring(0, i) : kalimat);
      kalimat = kalimat.substring(i + 1);
    }
  }
}

June 20, 2009

BigDecimal, BigInteger dan BigMistake

Filed under: Java — hjaya @ 11:41 pm

Harus diakui, judul post kali ini tidak orisinil. Tetapi, judulnya tetap saja menarik dan mungkin post kali ini akan bisa menjelaskan tentang BigMistake ketika kita memakai BigDecimal.

1. BigMistake pertama dalam memakai BigDecimal dan BigInteger adalah : runtime!! No doubt about it. Salah satu pelajaran yang bisa dipetik dari BigMistake ini adalah : Gunakan BigDecimal dan BigInteger hanya jika diperlukan, sebisa mungkin gunakan double atau float. Tetapi, satu yang pasti, untuk perkara duit gunakan BigDecimal.

2. MathContext adalah wajib
Kode program berikut ini akan mengalikan 0.1 dengan 10. Hasil yang seharusnya keluar adalah 1. Tetapi, coba tebak output apa yang akan anda terima?

public static void main(String[] args) {
  BigDecimal _ZeroPointOne = new BigDecimal(0.1);
  System.out.println(_ZeroPointOne.multiply(BigDecimal.TEN));
}

Alih-alih mendapatkan output 1 atau 1.000 atau yang sejenis, anda akan memperoleh output 1.0000000000000000555111512312578270211815834045410156250.. mengejutkan…tentu saja.

Untuk mengatasi hal ini, Java sebenarnya sudah menyiapkan solusi, yaitu MathContext. Secara sederhana, MathContext adalah sebuah object yang menentukan setting-setting yang akan dipakai dalam kalkulasi, seperti presisi dan mode pembulatan.

Mari kita lihat output apa yang akan diterima jika kita menggunakan MathContext :

public static void main(String[] args) {
  MathContext ctx = new MathContext(10, RoundingMode.HALF_UP);
  BigDecimal _ZeroPointOne = new BigDecimal(0.1, ctx);
  System.out.println(_ZeroPointOne.multiply(BigDecimal.TEN, ctx));
}

Yap.. ternyata hasil yang diperoleh adalah 1.000000000 .. hasil yang diharapkan tentunya.

Sekarang, apakah kita harus menyediakan sebuah MathContext dalam setiap operasi di BigDecimal. Sebaiknya iya dan sebaiknya MathContext yang dipakai dari awal sampai akhir penggunaan BigDecimal menggunakan context yang sama.

Agar tidak terlalu bingung mempelajari MathContext mungkin ada baiknya kita menggunakan MathContext standard yang sudah disediakan oleh Java. Ada empat buah MathContext yang sudah disediakan, yaitu UNLIMITED, DECIMAL32, DECIMAL64 dan DECIMAL128. Sebagai permulaan, gunakanlah MathContext.DECIMAL64

Lantas, bagaimana output yang akan kita peroleh dengan kode program di atas jika menggunakan MathContext DECIMAL64?

public static void main(String[] args) {
  MathContext ctx = MathContext.DECIMAL64;
  BigDecimal _ZeroPointOne = new BigDecimal(0.1, ctx);
  System.out.println(_ZeroPointOne.multiply(BigDecimal.TEN, ctx));
}

Hore, kita mendapatkan output 1.000000000000000.. hasil yang diharapkan dengan jumlah angka di belakang koma yang cukup panjang.

Sebagai best practice, gunakan selalu MathContext dalam operasi-operasi perhitungan yang melibatkan BigDecimal dan untuk kebanyakan perhitungan, MathContext.DECIMAL64 sudah sangat mumpuni.

Method isPowerOfTwo(long number)

Filed under: Java — hjaya @ 9:16 am

1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024…

Di atas itu adalah barisan bilangan yang berada dalam bentuk 2n, dimana n = 0, 1, 2, 3.. ; n ε bilangan cacah.

Dan dibawah ini adalah method static untuk memeriksa apakah sebuah bilangan (long) merupakan bilangan 2n :

public static boolean isPowerOfTwo(long number) throws ArithmeticException{
  if (number < 1) throw new ArithmeticException("number must be greater than 0");
  return (number & (number - 1)) == 0;
}

June 19, 2009

Toleransi Pattern Pada Kelas DateFormat..

Filed under: Java — hjaya @ 10:06 am

Di Java, kita mengenal kelas DateFormat. Kelas ini berfungsi untuk mem-parsing String (dalam pattern tertentu) menjadi Date dan juga sebaliknya.

Secara singkat, kita biasa menggunakan kelas DateFormat seperti ini :

  public class Main {
    public static void
main(String... args) {
      String pattern = "yyyyMMdd";
      DateFormat dateFormatter = new SimpleDateFormat(pattern);
      String _17_Juni_09 = "20090617";

      try {
        System.out.println(dateFormatter.parse(_17_Juni_09));
      } catch (ParseException e) {
        e.printStackTrace();
      }
    }
  }

Ada satu hal menarik yang akan kita bahas dalam kode program di atas. Yaitu ParseException. Secara default, DateFormat akan berusaha sebaik-baiknya untuk mem-parsing parameter yang dikirimkan. Hal ini bisa berakibat baik dan bisa juga berakibat buruk. Sebagai best practice, sebaiknya kita mempelajari keburukan dari toleransi dari DateFormat.

Contoh 1 : Sebuah String “20090617″ akan diterjemahkan sebagai 17 Juni 2009 (benar)

Parameter yang dikirim logically dan physically benar. Logically benar karena tanggal 17 Juni 2009 memang benar-benar ‘ada’ dan physically benar karena mengikuti kaedah penulisan tanggal yang benar

Contoh 2 : Sebuah String “20090635″ akan diterjemahkan sebagai 5 Juli 2009 (bisa benar, bisa salah)

Parameter yang dikirim logically salah namun physically benar. Logically salah karena tanggal 35 Juni 2009 sebenarnya tidak ‘ada’ tetapi physically benar karena mengikuti kaedah penulisan tanggal yang benar.

Contoh 3 : Sebuah String “200906a7″ akan menghasilkan ParseException (benar)

Parameter yang dikirim logically salah dan physically salah.

Pada contoh ke-2, mengapa DateFormat tidak melempar exception?? Karena memang secara default, DateFormat akan mentolerir kesalahan logic dan akan tetap berusaha mem-parsing input yang diberikan.

Pada contoh ke-3, mengapa DateFormat melempar exception?? Karena input yang dikirim memang tidak bisa diparsing.

Kesimpulan yang bisa kita tarik sampai saat ini adalah DateFormat secara default hanya akan melempar exception jika data physically salah sehingga proses parsing pasti gagal. Tetapi, bagaimana dengan data yang logically salah?

Secara default, DateFormat akan mentolerir hal ini dan dengan senang hati mencoba ‘membenarkan’ input yang diterima. Pada contoh di atas, tanggal 35 Juni 2009 akan diterjemahkan menjadi 5 Juli 2009. Hal inilah yang bisa berakibat baik dan juga bisa berakibat buruk. Berakibat baik kalau programmer sudah mengerti akan perilaku ini dan memang sengaja membiarkan DateFormat melakukannya.

Tetapi, kebanyakan coder (bukan programmer) akan terjebak dengan feature ini dan mengira bahwa input yang dikirim tidak bermasalah dan aplikasi berjalan baik-baik saja. Well, memang benar bahwa aplikasi berjalan baik-baik saja… tetapi ketidak-aware-an para coder akan berakibat fatal pada Business Process.

Contoh mudah yang bisa kita karang : Misalkan sebuah aplikasi perbankan menjanjikan pembayaran bunga pada tanggal 25 setiap bulannya. Tetapi karena kesalahan ketik, user memasukkan tanggal 35. Karena aplikasi tidak mengeluarkan Exception, data tersebut tersimpan dengan mulus di database dan akibatnya pembayaran bunga molor 10 hari dari yang sudah dijanjikan. Satu atau dua nasabah dengan rekening yang kecil mungkin tidak terlalu ambil pusing. Tetapi bagaimana dengan nasabah dengan rekening yang besar yang memang setiap bulannya menanti-nanti tanggal 25??

Untuk mengantisipasi hal ini, kita dapat ‘meminta’ DateFormat untuk menghilangkan rasa toleransinya. Yaitu dengan menambahkan setLenient(false). Dengan tidak adanya toleransi dari DateFormat maka input “20090635″ akan ditolak dan aplikasi akan mengeluarkan Exception dan Business Error pun dapat dihindari. Di bawah ini adalah contoh kode program yang menghilangkan rasa toleransi dari DateFormat :

  public class Main {
    public static void
main(String... args) {
      String pattern = "yyyyMMdd";
      DateFormat dateFormatter = new SimpleDateFormat(pattern);
      dateFormatter.setLenient(
false);
      String _35_Juni_09 = "20090635";

      try {
        System.out.println(dateFormatter.parse(_35_Juni_09));
      } catch (ParseException e) {
        e.printStackTrace();
      }
    }
  }

March 24, 2009

ADF Facelet (Quickstart)

Filed under: Java — hjaya @ 3:17 am
  1. Peroleh file-file berikut (dari http://facelets.dev.java.net):
    • adf-facelets.jar
    • jsf-facelets.jar
    • el-ri.jar
    • el-api.jar
  2. Libatkan file-file tersebut dalam library JDeveloper, jangan lupa untuk melibatkan 3 (tiga) buah library dari JDeveloper sendiri, yaitu JSP Runtime dan ADF Faces Runtime. Seperti pada gambar di bawah ini :
    Libraries
  3. Tambahkan kode berikut di dalam web.xml :
    <context-param>
      <param-name>
    oracle.adf.view.faces.ALTERNATE_VIEW_HANDLER</param-name>
      <param-value>
    com.sun.facelets.FaceletViewHandler</param-value>
    </context-param>

December 18, 2008

Konversi integer jadi string

Filed under: Java — hjaya @ 9:33 am

Program berikut ini akan mengonversi int menjadi String.

Contohnya :

  • 5 : lima
  • 72 : tujuh puluh dua
  • 341 : tiga ratus empat puluh satu
  • 9999 : sembilan ribu sembilan ratus sembilan puluh sembilan
  • 1000 : seribu
  • 11 : sebelas
  • 6523409 : enam juta lima ratus dua puluh tiga ribu empat ratus sembilan

Saya kira tidak perlu teori yang bermacam-macam, langsung saja kita lihat contoh programnya :

public class Say {
  public static String convert(int angka) throws Exception{
    assert angka >= 0;

    if (angka == 0) return "nol";
    if (angka == 1) return "satu";
    if (angka == 2) return "dua";
    if (angka == 3) return "tiga";
    if (angka == 4) return "empat";
    if (angka == 5) return "lima";
    if (angka == 6) return "enam";
    if (angka == 7) return "tujuh";
    if (angka == 8 ) return "delapan";
    if (angka == 9) return "sembilan";
    if (angka == 10) return "sepuluh";
    if (angka == 11) return "sebelas";

    if (angka < 20) return convert(angka - 10) + " belas";

    if (angka < 100){
      if (angka % 10 > 0) return convert(angka / 10) + " puluh " + convert(angka % 10);
      else return convert(angka / 10) + " puluh";
    }

    if (angka == 100) return "seratus";

    if (angka < 200) return "seratus " + convert(angka - 100);

    if (angka < 1000){
      if (angka % 100 > 0) return convert(angka / 100) + " ratus " + convert(angka % 100);
      else return convert(angka / 100) + " ratus";
    }

    if (angka == 1000) return "seribu";

    if (angka < 2000) return "seribu " + convert(angka - 1000);

    if (angka < 1000000){
      if (angka % 1000 > 0) return convert(angka / 1000) + " ribu " + convert(angka % 1000);
      else return convert(angka / 1000) + " ribu";
    }

    if (angka < 1000000000){
      if (angka % 1000000 > 0) return convert(angka / 1000000) + " juta " + convert(angka % 1000000);
      else return convert(angka / 1000000) + " juta";
    }

    if (angka <= 2147483647){
      if (angka % 1000000000 > 0)
        return convert(angka / 1000000000) + " milyar " + convert(angka % 1000000000);
      else return convert(angka / 1000000000) + " milyar";
    }

    throw new Exception("Not Supported Yet");
  }

  public static void main(String[] args) {
    try {
      System.out.println(Say.convert(2147483647));
    }
    catch (Exception e) {System.out.println(e.getMessage());}
  }
}

December 15, 2008

Insertion Sort

Filed under: Sorting Algorithm — hjaya @ 9:32 am

Pada prinsipnya, Insertion Sort mengambil suatu elemen dari array lalu “menyisipkannya” di tempat yang benar. Proses dilakukan terus menerus sampai seluruh elemen telah berada di tempat yang benar.

Coba perhatikan ilustrasi di bawah ini..

( 5 1 4 2 8 ) -> ( 1 5 4 2 8 ) karena 5 > 1
( 1 5 4 2 8 ) -> ( 1 4 5 2 8 ) karena 5 > 4
( 1 4 5 2 8 ) -> ( 1 4 2 5 8 ) karena 5 > 2, -> ( 1 2 4 5 8 ) karena 4 > 2
( 1 2 4 5 8 ) -> ( 1 2 4 5 8 )

Berikut ini saya sediakan implementasi dari Insertion Sort dalam java :

public class Sort {
  private Sort(){}

  public static <T extends Comparable> T[] insertion(T[] arr, boolean isAscending){
    for (int i = 1; i < arr.length; i++) {
      int j = i;
      T t = arr[i];
      while ((j > 0) && (
          isAscending && (arr[j - 1].compareTo(t) > 0) ||
          !isAscending && (arr[j - 1].compareTo(t) < 0))) {
        arr[j] = arr[j - 1];
        j--;
      }
      arr[j] = t;
    }

    return arr;
  }

  public static T[] insertion(T[] arr, Comparator comparator, boolean isAscending){
    for (int i = 1; i < arr.length; i++) {
      int j = i;
      T t = arr[i];
      while ((j > 0) && (
          isAscending && (comparator.compare(arr[j - 1], t) > 0) ||
          !isAscending && (comparator.compare(arr[j - 1], t) < 0))) {
        arr[j] = arr[j - 1];
        j--;
      }
      arr[j] = t;
    }

    return arr;
  }
}

Untuk eksekusi kode di atas, silahkan lihat post Bubble Sort.

December 14, 2008

Selection Sort

Filed under: Sorting Algorithm — hjaya @ 1:49 pm

Prinsip utama dari Selection Sort adalah mencari nilai terkecil dari suatu array dan menempatkannya sebagai elemen yang paling depan dengan cara menukar elemen tersebut dengan elemen yang paling depan. Setelah ditempatkan di paling depan, algoritma kembali melakukan iterasi, tetapi kali elemen yang paling depan tidak diikutkan karena sudah “terurut” dengan baik. Begitu seterusnya..

Untuk mode descending, nilai yang dicari adalah nilai terbesar.

Untuk lebih jelasnya silahkan perhatikan dua buah ilustrasi di bawah ini (ascending)

  1. Ilustrasi dengan angka (dari Wikipedia)

    ( 5 1 4 2 8 ) -> ( 1 5 4 2 8 ) Nilai min : 1, Target pertukaran : 5
    ( 1 5 4 2 8 ) -> ( 1 2 4 5 8 ) Nilai min : 2, Target pertukaran : 5
    ( 1 2 4 5 8 ) -> ( 1 2 4 5 8 ) Nilai min : 4, Target pertukaran : 4
    ( 1 2 4 5 8 ) -> ( 1 2 4 5 8 ) Nilai min : 5, Target pertukaran : 5

  2. Ilustrasi dengan gambar (refresh browser anda jika gambar tidak bergerak)

Berikut ini saya sediakan implementasi Selection Sort dalam Java..

public class Sort {
  private Sort(){}

  public static <T extends Comparable> T[] selection(T[] arr, boolean isAscending){
    for (int i = 0; i < arr.length - 1; i++){
      int min = i;
      for (int j = i + 1; j < arr.length; j++)
        if ((isAscending && (arr[min].compareTo(arr[j]) > 0)) ||
          (!isAscending && (arr[min].compareTo(arr[j]) < 0)))
          min = j;

      T t = arr[i];
      arr[i] = arr[min];
      arr[min] = t;
    }

    return arr;
  }

  public static T[] selection(T[] arr, Comparator comparator, boolean isAscending){
    for (int i = 0; i < arr.length - 1; i++){
      int min = i;
      for (int j = i + 1; j < arr.length; j++)
        if ((isAscending && (comparator.compare(arr[min], arr[j]) > 0)) ||
          (!isAscending && (comparator.compare(arr[min], arr[j]) < 0)))
          min = j;

      T t = arr[i];
      arr[i] = arr[min];
      arr[min] = t;
    }

    return arr;
  }
}

Untuk eksekusi kode di atas, silahkan lihat post Bubble Sort.

Yahoo Emoticon

Filed under: Uncategorized — hjaya @ 1:56 am

Ga ada ide mau nulis apa.. jadinya cuman naruh-naruh yahoo emoticon ajah..

: ) happy   : ( sad  
; ) winking   : D big grin  
; ; ) batting eyelashes   > : D < big hug  
: ” > blushing   : – / confused  
: x love struck   : P tongue  
: – * kiss   = ( ( broken heart  
: – O surprise   X ( angry  
: > smug   B – ) cool  
: – S worried   # : – S whew!  
> : ) devil   : ( ( crying  
: ) ) laughing   : | straight face  
/ : ) raised eyebrows   = ) ) rolling on the floor laugh  
O : – ) angel   : – B nerd  
= ; talk to the hand   I – ) sleepy  
8 – | rolling eyes   L – ) loser  
: – & sick   : – $ don’t tell anyone  
[ - ( no talking   : O ) clown  
8 - } silly   < : - P party  
( : | yawn   = P ~ drooling  
: - ? thinking   # - o d'oh  
= D > applause   : - S S nail biting  
@ - ) hypnotized   : ^ o liar  
: - w waiting   : - < sigh  
> : P phbbbbt   < ) : ) cowboy  
: @ ) pig   3 : - O cow  
: ( | ) monkey   ~ : > chicken  
@ } ; - rose   % % - good luck  
* * = = flag   ( ~ ~ ) pumpkin  
~ O ) coffee   * - : ) idea  
8 - X skull   = : ) bug  
> - ) alien   : - L frustrated  
[ - O < praying   $ - ) money eyes  
: - " whistling   b - ( feeling beat up  
: ) > - peace sign   [ - X shame on you  
\ : D / dancing   > : / bring it on  
; ) ) hee hee   o - > hiro  
o = > billy   o - + april  
( % ) yin yang   : - @ chatterbox  
^ : ) ^ not worthy   : - j oh go on  
( * ) star   : ) ] on the phone  
: – c call me   ~ X ( at wits’ end  
: – h wave   : – t time out  
8 – > day dreaming   : – ? ? i don’t know  
% – ( not listening   : o 3 puppy dog eyes  
X _ X i don’t wanna see   : ! ! hurry up!  
\ m / rock on!   : – q thumbs down  
: – b d thumbs up   ^ # ( ^ it wasn’t me  
: b z bee   : a r ! pirate  
[ . . ] transformer  

Tidak semua emoticon yang ada di atas dapat anda pakai. Ada beberapa emoticon yang hanya bisa digunakan di Yahoo Messenger versi web

Older Posts »

Blog at WordPress.com.