Saturday, March 2, 2013

Perkenalan Scala dari Java

Belakangan ini gw sibuk mengembangkan Ngajak Jalan, sebuah situs jodoh untuk mencari pacar. Karena sedang belajar Scala, gw membuat Ngajak Jalan dengan Scala.

Banyak yang bilang bahwa Scala adalah "Java yang lebih baik". Terlepas dari benar atau tidaknya, gw akan menunjukkan bagaimana sebuah program Java ditulis dalam Scala. Oh ya, iklan dulu: Untuk yang jomblo, jangan lupa bergabung di Ngajak Jalan. OK, lanjut :)

Andaikan kita punya input.txt dengan isi sebagai berikut:

Nama	Usia
Thomas	30
Budi	28
Wati	25
Jojon	38
Santi	20

Kita ingin membaca dokumen tersebut lalu menampilkan isinya jika usia lebih kecil atau sama dengan 30. Berikut ini tampilan yang diharapkan:

Thomas = 30
Budi = 28
Wati = 25
Santi = 20

Dengan Java:

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Program {
    public static void main(String args[]) throws Exception {
        Scanner scanner = new Scanner(new File("input.txt"));
        List<String> lines = new ArrayList<String>();

        scanner.useDelimiter("\n");

        while (scanner.hasNext())
            lines.add(scanner.next());

        scanner.close();

        lines = lines.subList(1, lines.size());

        for (String line : lines) {
            String[] tokens = line.split("\t");
            String name = tokens[0];
            int age = Integer.parseInt(tokens[1]);

            if (age <= 30)
                System.out.println(name + " = " + age);
        }
    }
}

Mari kita "Scala-kan" program di atas. Agar mudah dimengerti, mari kita lakukan bertahap. Tahap pertama adalah menghilangkan titik koma dan men-Scala-kan elemen yang terpaksa harus diubah (agar tidak compile error):

import java.io.File
import java.util.Scanner
import collection.mutable.ListBuffer

object Program {
    def main(args: Array[String]) {
        val scanner = new Scanner(new File("input.txt"))
        var lines = new ListBuffer[String]()

        scanner.useDelimiter("\n")

        while (scanner.hasNext())
            lines.+=(scanner.next())

        scanner.close()

        lines = lines.slice(1, lines.size)

        lines.foreach(line => {
            val tokens = line.split("\t")
            val name = tokens(0)
            val age = Integer.parseInt(tokens(1))

            if (age <= 30)
                System.out.println(name + " = " + age)
        })
    }
}

Ini program Scala lho, mirip Java kan? Bagaimana rasanya tanpa titik koma? Lebih enak dilihat? Mari kita hilangkan beberapa noise:

import java.io.File
import java.util.Scanner
import collection.mutable.ListBuffer

object Program {
    def main(args: Array[String]) {
        val scanner = new Scanner(new File("input.txt"))
        var lines = new ListBuffer[String]()

        scanner useDelimiter "\n"

        while (scanner.hasNext)
            lines += scanner.next

        scanner.close()

        lines = lines slice(1, lines.size)

        lines.foreach(line => {
            val tokens = line split "\t"
            val name = tokens(0)
            val age = tokens(1).toInt

            if (age <= 30)
                println(s"$name = $age")
        })
    }
}

Mirip program sebelumnya, tapi sedikit lebih "bersih". Kita juga menggunakan fitur baru di Scala 2.10 bernama string interpolation. Mari kita peringkas lagi dengan lebih idiomatik:

import io.Source._

object Program extends App {
    val lines = fromFile("input.txt").getLines().toList drop 1
    val tokens = lines.map(_ split '\t').map(arr => (arr(0), arr(1).toInt))

    tokens.foreach(
        _ match {
            case (name, age) if age <= 30 => println(s"$name = $age")
            case _ =>
        }
    )
}

OK, ini mulai terlihat asing—mari kita bahas.

  • extends App adalah shortcut untuk main() yang biasa kamu kenal.
  • fromFile adalah metode dari io.Source untuk membaca file.
  • map adalah fungsi yang mentransformasi sebuah koleksi ke koleksi lain. 
  • map yang pertama mengubah list String ke list Array ([Nama,Usia],[Thomas,30],…). 
  • map yang kedua mengubah list Array ke list Tuple ((Nama,Usia),(Thomas,30),…). Tuple ini dibutuhkan untuk match-case.

Kalau program kita diubah ke bahasa manusia:

  • Baca input.txt baris per baris, taruh di list dan buang elemen pertama.
  • Untuk setiap elemen di list, pisahkan dengan TAB, lalu buat berpasangan (nama-usia).
  • Untuk setiap elemen di list, namai name untuk data kiri dan age untuk data kanan, tapi hanya kalau elemennya merupakan sebuah pasangan dan age lebih kecil atau sama dengan 30. Tampilkan di layar.

Bagaimana? Menarik? Kalau ada yang belum jelas, mohon tulis di komentar supaya bisa gw jawab. Kalau peminatnya banyak, gw akan melanjutkan blognya. Jangan lupa kasih ide apa yang perlu dibahas :) Eh tunggu, iklan lagi deh: Ngajak Jalan adalah tempat untuk mencari TTM, pacar sampai istri. Jangan lupa di-share kalau bermanfaat (tulisannya, bukan soal cari TTM-nya)!

2 comments:

  1. boy lanjut ke memulai belajar scala dari tools2 yang dibutuhin....sampe connect db,,,,

    ReplyDelete
    Replies
    1. ide bagus gan! blog berikutnya tentang cara setup scala. blog berikutnya konek ke DB.

      Delete