.::. Hendra Jaya .::.

November 30, 2008

Comparable & Comparator

Filed under: Java — hjaya @ 12:07 pm

Interface Comparable (java.lang.Comparable) adalah sebuah interface yang berjanji (sebenarnya memberikan kontrak :P ) bahwa semua kelas yang mengimplement dirinya akan dapat di-naturally order. Sungguh membingungkan…

Ok.. mari kita buat lebih mudah dengan skenario ini. Misalkan anda punya kelas Person dan anda membuat segudang instans dari Person. Bagaimana caranya anda mengurutkan instans Person yang segudang ini?” Saya harap anda tidak berpikir untuk mengimplementasi Bubble Sort atau Quick Sort atau algoritma sorting lainnya :D .. Untungnya, Java memiliki sebuah kelas yang berguna untuk masalah ini, yaitu kelas Collections (tentang kelas Collections ini sendiri akan kita bahas di post lain). Kelas ini memiliki sebuah method canggih yang bernama SORT. Horeee!! Masalah dapat diselesaikan.

Akan tetapi… method sort memiliki konstrain yang harus dipenuhi.. yaitu “Method ini hanya bisa men-sort kumpulan objek yang comparable”. Dengan kata lain, objek yang ingin anda sort harus mengimplement interface Comparable. Tetapi mengapa harus Comparable? Karena memang desainnya seperti itu :P . Bercanda.., yang sebenarnya adalah karena interface Comparable memiliki method compareTo(T t) yang akan digunakan oleh method sort.

Sekarang, kita akan membahas teknisnya. Method compareTo akan mengembalikan integer. Karena integer memiliki tiga state, yaitu “Sama dengan 0″, “Besar dari 0″ dan “Kurang dari 0″, maka method sort menerjemahkan ketiga state tersebut sebagai berikut :

  1. Sama dengan 0
    Jika compareTo mengembalikan 0, maka method sort akan mengasumsikan bahwa objek ini (anggap saja namanya person1) sama dengan objek yang dibandingkan (anggap saja namanya person2).
  2. Besar dari 0
    Jika compareTo mengembalikan integer yang lebih besar dari 0, maka method sort akan mengasumsikan bahwa person1 lebih besar dari person2 sehingga person1 akan ditempatkan di belakang person2 dalam list yang sudah disusun ulang : a, b, c.. person2, person1, x, y, z
  3. Kurang dari 0
    Jika compareTo mengembalikan integer yang lebih kecil dari 0, maka method sort akan mengasumsikan bahwa person1 lebih kecil dari person2 sehingga person1 akan ditempatkan di depan person2 dalam list yang sudah disusun ulang : a, b, c.. person1, person2, x, y, z

Apakah asumsi ini hanya digunakan dalam kelas Collections? Tidak. Banyak kelas (kalau tidak semua) di Java dan mungkin juga di seluruh dunia menggunakan asumsi ini.
Jika method compareTo mengembalikan integer kurang dari 0, maka objek tersebut lebih kecil dibanding objek yang dibandingkan dan sebaliknya.
Jika method compareTo mengembalikan integer besar dari 0, maka objek itu dianggap sama. Tetapi asumsi ini bukanlah suatu konvensi. Di akhir post ini, saya akan memberikan contoh dimana asumsi yang dipakai adalah asumsi kebalikannya.

Lihatlah contoh ini :

public class Person implements Comparable<Person> {
  private Integer id;
  private String name;
  private Date birthday;

  @Override
  public int compareTo(Person p) {
    return id.compareTo(p.id);
  }
}

Tetapi bagaimana jika kelas Person tidak mempunyai field id dan ingin membandingkan sebuah instans Person dengan instans Person lain menggunakan field name dan birthday? Coba lihat ini :

public class Person Person implements Comparable<Person> {
  private String name;
  private Date birthday;

  @Override
  public int compareTo(Person p) {
    if (name.compareTo(p.name) != 0) return name.compareTo(p.name);
    else return birthday.compareTo(p.birthday);
  }
}

Dalam kode di atas, anda dapat melihat bahwa name dibandingkan terlebih dahulu ketimbang birthday. Ini adalah algoritma saya, anda dapat menggunakan algoritma anda sendiri yang sesuai dengan kebutuhan anda :D

Hal lain yang ingin saya beritahukan adalah :

  1. Sebaiknya selalu implement Comparable
    Kita tidak tahu siapa yang akana me-reuse kelas kita di masa nantinya dan di-reuse untuk apa. Tetapi satu hal yang pasti, mereka mungkin perlu membandingkan dua (atau lebih) instans dari kelas kita (untuk sorting, searching, atau apapun).
  2. Hasil yang dikeluarkan dari method compareTo harus mencerminkan hasil yang keluar dari method equals.
    Anda akan terlihat bodoh jika anda mendesain suatu kelas dimana method compareTo menghasilkan nilai selain 0 tetapi method equals menghasilkan true :D

Ok. Diskusi tentang interface Comparable cukup sampai disini. Mari kita membicarakan interface Comparator. Sebenarnya, interface Comparable harus digunakan untuk natural order dan interface Comparator digunakan untuk total order, tetapi sulit untuk membuat dua buah strategi pengorderan. Jadi, mari kita abaikan saja tentang natural dan total order dan membicarakan tentang hal lain.

Untuk saat ini, anggap saja bahwa interface Comparable dipakai jika method compareTo diletakkan di dalam kelas itu sendiri dan interface Comparator digunakan jika kelas tersebut tidak mengimplement interface Comparable.

Ini adalah kelas Person dan kelas PersonComparator :

public class Person {
  private String name;
  private Date birthday;
  // Getter & Setter
}

public class PersonComparator implements Comparator<Person> {
  @Override
  public int compare(Person p1, Person p2) {
    if (p1.getName().compareTo(p2.getName()) != 0) return p1.getName().compareTo(p2.getName());
    else return p1.getBirthday().compareTo(p2.getBirthday());
  }
}

Apakah ini berarti bahwa kita harus membuat sebuah kelas Comparator untuk setiap kelas yang tidak mengimplement Comparable? Ya… Tapi kita dapat memberikan semacam akal-akalan disini…, Coba lihat skenario ini..

public class Person {
  // Attributes
  // Getter & Setter
}

public class Pet {
  // Attributes
  // Getter & Setter
}

Misalkan anda mempunyai dua kelas yang tidak mengimplement Comparable. Agar dapat membandingkan instans dari kelas ini, anda seharusnya membuat minimal dua buah kelas Comparator dan ini tidak baik, karena partner anda akan bingung dengan banyaknya kelas yang tersebar di dalam package.

Sekarang, ketimbang memroduksi kelas Comparator sebanyak itu, anda dapat membuat semacam kelas OmniComparator, dan disinilah seninya :D .

public class OmniComparator {
  Comparator<Person> personComparator = new PersonComparator();
  Comparator<Group> groupComparator = new GroupComparator();

  // Getter -- No need to provide any setter

  // Inner classes -- The trick goes here
  class PersonComparator implements Comparator<Person>{
    @Override
    public int compare(Person p1, Person p2) {
      // PUT YOUR CODE HERE
    }
  }

  class GroupComparator implements Comparator<Group>{
    @Override
    public int compare(Group g1, Group g2) {
      // PUT YOUR CODE HERE
    }
  }

}

Dengan cara ini.. anda tidak perlu beternak kelas. Cukup buat satu omniclass dan source code anda akan lebih mudah dibaca.

Bagaimana dengan kelas Collections? Bagaimana kita menggunakan method sort-nya? Jangan kuatir.. :P Desainer kelas Collections telah menyediakan jawabannya bagi kita. Kelas Collections class datang tidak hanya dengan satu method sort. Kelas ini datang dengan beberapa method sort dan salah satunya memungkinkan kita untuk menyortir objek-objek yang non-comparable asalkan kita menyediakan sebuah comparator untuk objek-objek tersebut. Method itu ialah sort(List list, Comparator c). Hoorrreee!!

Java telah menyediakan method untuk searching dan sorting melalui kelas Collections. Dengan mengombinasikan interface Comparable/Comparator dengan kelas Collections, kita dapat mengurangi effort yang kita keluarkan untuk coding tetapi dengan mudah dapat melakukan searching dan sorting.

Seperti yang telah dijanjikan sebelumnya, sekarang saya akan memberikan sebuah pertunjukan dimana integer positif tidak selalu berarti lebih besar dan integer negatif tidak selalu berarti lebih kecil. Mari kita lihat skenarionya :
Misalkan anda mempunyai beberapa tim dan juga poinnya secara berturut-turut seperti ini:
- Arsenal 19
- Chelsea 16
- Liverpool 17
- Man United 20

Bagaimana cara anda mengurutkan mereka menurut poinnya?
Apakah itu seperti ini :
1. Chelsea 16
2. Liverpool 17
3. Arsenal 19
4. Man United 20

atau begini :
1. Man United 20
2. Arsenal 19
3. Liverpool 17
4. Chelsea

OK, sekarang lihat kelas di bawah ini :
public class Team implements Comparable<Team>{
  private int win;
  private int draw;
  private int lose;
  // Getter & Setter
  public int getPoint(){return win * 1 + draw;}

    @Override
    public int compareTo(Team t) {
      // PUT YOUR CODE HERE
    }
}

Di dalam liga sepakbola, biasanya tim diurutkan menurut jumlah poin, jumlah kemenangan, selisih gol dan seterusnya. Untuk mempermudah, kita anggap saja bahwa tim diurutkan hanya berdasarkan poinnya dan kita abaikan atribut yang lain.
Apakah anda sudah melihat sesuatu yang menarik disini? Yap. Jika sebuah tim memiliki poin lebih besar dari tim lain, maka tim tersebut haruslah ditempatkan di tempat yang lebih dulu di klasemen. Jadi, bagaimanakah implementasi dari method compareTo agar tim-tim ini dapat terurut dengan baik?

Apakah seperti ini?
@Override
public int compareTo(Team t) {
  if (getPoint() == t.getPoint()){
    // Another algorithm
  }
  else return getPoint() - t.getPoint();
}

Atau seperti ini?
@Override
public int compareTo(Team t) {
  if (getPoint() == t.getPoint()){
    // Another algorithm
  }
  else return t.getPoint() - getPoint();
}

Jika anda menggunakan method sort yang dibundel dalam kelas Collections, maka implementasi pertama akan menghasilkan sebuah klasemen aneh dimana tim dengan poin yang lebih besar akan ditempatkan lebih ke bawa dan ini sangatlah kejam :( . Pada titik ini, saya ingin memberi tahu anda tentang nilai yang dikembalikan oleh method compareTo tidaklah strict kepada aturan “Positif adalah lebih besar, Negative adalah lebih kecil, dan 0 adalah sama”. Anda dapat mengubahnya sesuai dengan kasus yang anda hadapi.

Sekian post tentang interface Comparable dan Comparator. Terima kasih telah membaca

November 29, 2008

Object Serialization

Filed under: Java — hjaya @ 6:54 am

Serializable secara teori didefinisikan sebagai “Mengubah sebuah object menjadi barisan bit sedemikian rupa sehingga object tersebut dapat disimpan ke dalam secondary memory.”

Di Java, agar sebuah kelas dapat diserialisasi, maka kelas itu harus mengimplementjava.io.Serializable untuk memberitahu Java Virtual Machine bahwa instans-instans dari kelas ini dapat diserialisasi dan disimpan di dalam secondary memory such sebagai file atau lebih jauh lagi, dikirim via jaringan.

Beberapa hal yang perlu anda ketahui tentang object serialization:

  1. Security
    Isu penting dalam serialisasi adalah sekuriti. Karena, ketika sebuah objek diserialisasi, objek tersebut menjadi barisan bit-bit yang tersimpan dalam sebuah file biner. Jika seseorang dapat mengakses file tersebut (yang merupakan hasil serialisasi) dan memanipulasi bit-bit itu, maka objek-objek anda telah di-hack dan hal ini dapat dilakukan dengan mudah karena access modifier apapun tidak akan berpengaruh lagi :D
  2. State dari suatu objek
    Satu hal yang perlu dipertimbangkan ketika men-serialisasi suatu objek adalah state dari objek tersebut. Banyak objek berubah menurut waktu dan ada juga objek-objek yang sangat dependent kepada environment-nya. Sebagai contoh, sebuah object dari kelas Thread biasanya berubah dari waktu ke waktu dan sebuah object dari kelas Socket sangat spesifik terhadap workstation tertentu pada waktu tertentu. Berdasarkan inilah, maka Java memutuskan untuk membiarkan anda menentukan kelas mana yang boleh diserialisasi dan mana yang tidak.
  3. Keyword Static
    Hal tricky yang harus anda pertimbangkan ketika memutuskan apakah harus mengimplement interface Serializable atau tidak adalah keyword static. Sekarang perhatikan baik-baik kelas java.lang.Math!! Kelas ini tidak tergantung waktu dan juga tidak tergantung mesin ataupun JVM, tetapi kelas ini tidak serializable. Kenapa? Karena semua fitur yang ditawarkan oleh kelas Math diberi tanda static yang berarti bahwa fitur-fitur tersebut akan di-load ke dalam JVM pada saat kompilasi. Hal ini berarti kelas tersebut tidak perlu diserialisasi. Jadi, jika suatu kelas hanya memiliki method private atau static, kemungkinan besar kelas tersebut tidak perlu mengimplement interface Serializable.
  4. Transient
    Hal terakhir yang perlu diketahui ketika mendesain suatu kelas yang serializable adlah keyword Transient. Field manapun yang dideklarasikan sebagai transient akan di-skip oleh JVM ketika JVM menserialisasi objek dari kelas tersebut.

Bagaimana jika kelas saya memiliki object reference(s)? Apakah JVM men-serialisasi mereka juga? Jawabannya adalah Ya. Selama object reference tersebut adalah reference yang menuju ke object yang serialisable, dan anda tidak memberikan keyword transient di sekitarnya, maka JVM akan men-serialisasi objek-objek yang direfer tersebut. :D

Hal lain yang menarik dalam serialisasi adalah field statik yang bernama serialVersionUID. Field ini merepresentasikan versi dari kelas. Artinya, kita tidak bisa me-load suatu objek jika serialVersionUID dari objek tersebut berbeda dengan serialVersionUID yang anda punya. Walaupun objek tersebut datang dari kelas yang sama, JVM akan menghalangi anda untuk me-load suatu serialized object ketika JVM mengetahui bahwa serialVersionUID-nya berbeda. Catatlah bahwa anda tidak perlu mengganti serialVersionUID jika anda hanya mengganti method-method atau field-field static. Ubahlah nilai serialVersionUID hanya jika anda mengubah field-field non-static pada objek tersebut.

Apakah nilai serialVersionUID acak? Tidak. Yah.. sebenarnya, anda dapat saja memberikan nilai yang anda inginkan tapi itu tidak baik karena serialVersionUID yang anda berikan mungkin saja sudah dipakai oleh kelas lain. Sangat dianjurkan untuk meng-generate nilai serialVersionUID dari IDE yang anda pakai seperti Eclipse, Netbeans atau JDeveloper.

public class SerializableObject implements Serializable{
  private static final long serialVersionUID = -6849794470754337710L;
}

November 28, 2008

Recursive

Filed under: Java — hjaya @ 5:27 pm

Menurut definisi rekursi di wikipedia, rekursi adalah suatu cara menyelesaikan masalah dimana solusi masalah tersebut datang dari setiap potongan kecil dari masalah tersebut.

Dalam rekursi, HARUS ada dua buah element, yaitu rekursi itu sendiri dan basis dari rekursi tersebut. Basis dapat dipandang sebagai “Kondisi dimana semuanya (rekursi) harus dihentikan”. Jika suatu proses rekursi tidak memiliki basis, maka proses rekursi itu akan memiliki awal tetapi tidak memiliki akhir.

Sebuah cara yang baik untuk memahami rekursi adalah dengan memahami perhitungan matematik berikut ini : Faktorial.
Apakah rumus dari f(n)?? Jawabnya adalah f(n) = n * f(n-1)
Dan apakah rumus untuk f(n-1)?? Jawabnya adalah f(n-1) = (n-1) * f(n-2)
Dan apakah rumus untuk f(n-2)?? Jawabnya adalah f(n-2) = (n-2) * f(n-3)
dan seterusnya.. sampai f(0) = 1

Dalam faktorial, basisnya adalah n = 0. Pada kondisi itu, rumus faktorial didefinisikan sebagai 1 dan pada kondisi ini jugalah semua proses berhenti.
Factorial

Dapat anda lihat pada gambar di atas bahwa :
f(3) = 3 * f(2)
Dimana f(2) = 2 * f(1)
Dimana f(1) = 1 * f(0)
Dimana (f0) = 1 ———> Dan disinilah proses rekursi kita berhenti
Jadi f(3) = 3 * 2 * 1 * 1 = 6 Yap! Inilah rekursi..

Ok.. berikut ini adalah beberapa contoh kode program yang memanfaatkan rekursi (Java):

public class Recursive{
  public int factorial (int n){
    if (n == 0) return 1;
    else return n * factorial(n - 1);
  }

  public int getNthFibonacciNumber (int n){
    if (n == 0) return 0;
    if (n == 1) return 1;
    else return getNthFibonacciNumber(n - 1) + getNthFibonacciNumber(n - 2);
  }

  // Asumsikan bahwa x >= y dan y > 0
  public int getGcd (int x, int y){
    if (y == 0) return x;
    return getGcd(y, x % y);
  }

}

Pada kode program yang anda lihat di atas, dapat ditemukan beberapa buah basis dalam proses rekursi. Dalam method factorial(int), hanya terdapat satu buah basis, tetapi pada method getNthFibonacciNumber(int), terdapat dua buah basis yang bisa menghentikan program.

Dalam konteks pemrograman, biasanya orang menggunakan fungsi rekursif untuk menyederhanakan source code. Tetapi pada saat runtime, kode yang rekursif akan mengonsumsi resource jauh lebih banyak ketimbang kode yang iteratif. Kendati demikian, sangatlah sukar untuk menggunakan iterasi pada struktur data Tree/Pohon.

Recursion

Tahun Kabisat

Filed under: Java — hjaya @ 9:42 am

Tahun kabisat adalah tahun yang jumlah harinya lebih banyak daripada tahun-tahun pada umumnya, yaitu 365 hari. Dalam kalender Gregorian yang lazim dipakai, tahun kabisat biasanya muncul empat tahun sekali. Dalam tahun kabisast, biasanya satu hari akan memiliki 365 hari (atau lebih) dan bulan Februari memiliki 29 hari.

Tahun kabisat secara matematis didefnisikan seperti ini : Sebuah tahun yang dapat dibagi habis oleh 4, tetapi tidak habis dibagi 100 atau sebuah tahun yang dapat dibagi habis oleh 400. Berdasarkan definisi ini, maka 1700, 1800 dan 1900 bukanlah tahun kabisat, tetapi 1600 dan 2000 adalah tahun kabisat. Dan tentu saja, 2004 dan 2008 adalah tahun kabisat.

Sebagai penutup, ini adalah kode program yang memeriksa apakah sebuah tahun kabisat atau bukan (Java):

public boolean isLeapYear(int year){
  return ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)));
}

February 29th - happens once in 4 year

November 27, 2008

0. Pendahuluan

Filed under: Design Pattern — hjaya @ 1:29 pm

Dalam men-desain software, seringkali kita dihadapkan pada beberapa masalah. Tenang saja, bukan anda yang pertama kali menemukan masalah tersebut. Sebagian besar masalah-masalah yang anda temui itu telah ditemukan dan (mungkin) telah dipecahkan oleh orang lain. Hal inilah yang kita kenal dengan design pattern. Tetapi, perlu anda ingat bahwa design pattern hanya terbatas pada level design, tidak melebar pada level arsitektur apalagi coding.

Design pattern dipopulerkan oleh Gang of Four (GoF), yaitu Erich Gamma, Richard Helm, Ralph Johnson, dan John Vlissides dalam buku mereka Design Patterns: Elements of Reusable Object-Oriented Software. Menurut saya, buku tersebut sebaiknya dijadikan buku saku saja, jangan dijadikan buku awal untuk belajar. Untuk belajar, sebaiknya anda membaca buku Head First Design Pattern, karena buku ini sangat konseptual dan mudah dipahami.

Dalam mendesain software, dikenal terminologi “Over Engineering” dimana desainer menerapkan terlalu banyak design pattern sedemikian rupa sehingga desainnya malah menjadi rumit dan membingungkan developer. Khusus untuk hal ini, dibutuhkan pengalaman dari desainer untuk menentukan trade off-nya.

Prinsip-prinsip yang harus diingat dalam design pattern :

  1. KISS (Keep It Simple Stupid)
    Jika anda menemukan sesuatu yang sudah sangat ribet, sadarlah dan pikirkanlah kembali apa yang anda kerjakan. Dalam banyak hal, sesuatu yang sangat rumit biasanya dapat dikerjakan dengan cara yang jauh lebih mudah.
  2. DRY (Don’t Repeat Yourself)
    Dalam fase implementasi, biasanya developer akan menyadari bahwa mereka hanya mengulang-ulang sesuatu yang sebenarnya sudah pernah dikerjakan. Jika hal ini terjadi satu dua kali, ikhlaskan saja. Tetapi jika hal ini sering terjadi, maka sudah saatnya anda menerapkan suatu design pattern
  3. Parsimony (Less is Better)
    Camkan selalu bahwa dalam rekayasa perangkat lunak “Sedikit itu Lebih Baik”!!
    - Bukankah semakin pendek kode program semakin mudah dibaca?
    - Bukankah semakin sedikit file maka alur program akan lebih mudah dipahami?
    - Bukankah semakin sedikit method/procedure dalam suatu kelas/program maka kelas/program tersebut akan lebih mudah dipahami?

Elements of reusable (Cover)
Design Pattern : Elements of reusable (Cover)

Head First Design Pattern (Cover)
Head First Design Pattern (Cover)

…. 1st

Filed under: Poems — hjaya @ 12:05 pm

di suatu masa ketika batu penghalang itu gagal kau pindahkan
dan gita tangismu begitu meronta hingga menghancurkan nyali
pahamilah walau sekejap bahwa aku selalu berada disini
siap untuk menemanimu dan merasakan semua jerit hatimu
dan jika memang itu semua harus kubayar dengan darah atau nanah
akan kulunasi agar genap apa yang memang pernah terucap

Dedicated to : Danilah Nur Muslim
Bandung, 19 Februari 2008

Lovina – Buleleng, Bali Utara

Filed under: Bali — hjaya @ 11:33 am

Lovina adalah sebuah pantai yang terletak di Bali utara, di Singaraja tepatnya. Lovina menyajikan banyak hal menarik yang bisa dinikmati, seperti lumba-lumba, seafood yang nikmat dan murah, dan tentu saja langit biru yang cerah. Sayangnya, jika anda ingin melihat lumba-lumba, anda harus tiba di pantai pagi-pagi sekali, sekitar jam 5 pagi WITA. Seandainya anda datang lebih siang, bersiaplah untuk membayar lebih mahal karena lumba-lumba lebih susah ditemukan ketika matahari bersinar. Di sore hari, ketika para nelayan pulang dari laut, anda dapat menikmati seafood yang segar, nikmat dan murah :P Jangan takut untuk bermalam di pantai ini, karena di sekitar pantai ini banyak tersedia penginapan yang sangat murah dan rumah makan yang harganya terjangkau.
Lovina

Sama seperti pantai-pantai lainnya di pulau Bali… untuk memasuki pantai ini, pengunjung tidak dipungut biaya sepeser pun. Sayangnya, di pantai Lovina, anda sebaiknya jangan terlalu berharap untuk melihat bule berjemur matahari. Kebanyakan bule yang datang ke sini biasanya bertujuan untuk beristirahat dan menghabiskan waktu bersama orang-orang yang mereka sayangi. Walau demikian, anda masih dapat menemui 1-2 bule yang berjemur di pantai. Sebagai informasi tambahan, pasir pantai Lovina tidak seputih pasir pantai Kuta, Sanur atau Balangan. Pasir pantai Lovina tergolong coklat dan tidak semenawan Kuta.

Kehidupan di pantai ini terasa sangat lambat mengingat sebagian besar orang yang datang kesini hanya duduk-duduk di kafe/restoran dan tidak beraktivitas di pantai seperti berenang dan berseluncur. Jika anda bertujuan untuk beristirahat dan hanya ingin bersantai, maka pantai Lovina adalah tempat yang cocok buat anda…

Menurut papan pemberitahuan yang dipasang di dekat pantai, asal muasal nama Lovina masihlah simpang siur. Beberapa kalangan mengatakan bahwa Lovina adalah nama yang diberikan oleh seorang Raja Buleleng. Kalangan lainnya mengatakan bahwa Lovina berasal dari bahasa latin yang artinya “Loving each other/Saling mencintai”. Ada juga pendapat konyol yang mengatakan bawah Lovina berarti “Love Ina” yang artinya “Mencintai Indonesia” (Indonesia seringkali disingkat Ina). Sungguh konyol.. :)
Saya sendiri lebih setuju dengan pendapat yang mengatakan bahwa Lovina adalah nama pemberian Raja Buleleng. Mengingat Lovina terletak di Kabupaten Buleleng dan Singaraja adalah nama ibukota kabupaten Buleleng :P
Sekedar menyegarkan kembali.. I Gusti Ketut Jelantik adalah pahlawan nasional yang memimpin Kerajaan Buleleng berperang melawan Belanda di perang puputan yang lebih dikenal dengan nama Perang Jagaraga.

Perjalanan dari Denpasar ke Singaraja memakan waktu sekitar dua jam. Tetapi, perjalanan dari Singaraja ke Denpasar akan memakan waktu lebih dari itu. Mengingat rute perjalanan yang harus naik turun menembus gunung dan jalan yang berliku-liku. Jika anda berencana untuk menempuh perjalanan dari Denpasar ke Singaraja, maka pastikan kendaraan anda mempunyai rem yang mumpuni. Sebaliknya, jika anda berencana untuk menempuh perjalanan dari Singaraja ke Denpasar, maka pastikan mesin kendaraan anda dalam keadaan prima untuk menempuh setiap tanjakan :D . Sebagai saran, sebaiknya hindari perjalanan malam..

Sewaktu saya dan teman-teman mengunjungi Lovina, kami menghabiskan waktu berfoto sebanyak-banyaknya dan salah satunya adalah ini..
With friends

Hello World

Filed under: Java — hjaya @ 10:07 am

Seperti layaknya seorang programmer yang baru belajar coding, semuanya pasti dimulai dengan “Hello World”, dan seperti inilah Hello World dalam blog ini :P
Ditulis pake bahasa Java (bukan Jawa :D )

public class HelloWorld{
  public static void main(String[] args){
    System.out.println("Hello World");
  }
}

Hello World!!

Blog at WordPress.com.