Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Android

Java 8 untuk Pengembangan Android: API Stream dan Libraries Tanggal dan Waktu

by
Difficulty:IntermediateLength:LongLanguages:
This post is part of a series called Java 8 for Android Development.
Java 8 for Android Development: Default and Static Methods

Indonesian (Bahasa Indonesia) translation by Sap (you can also view the original English article)

Dalam seri tiga bagian ini, kami telah menjelajahi semua fitur Java 8 utama yang dapat kamu gunakan di proyek Androidmu hari ini

Dalam Kode Cleaner Dengan Lambda Expressions, kami berfokus untuk memotong boilerplate dari proyek kamu menggunakan ekspresi lambda, kemudian dalam Default dan Static Methods, kami melihat bagaimana membuat ekspresi lambda ini lebih ringkas dengan menggabungkan dengan referensi metode. Kami juga Mengulangi Annotation dan cara mendeklarasikan method non-abstrak di interfaces Anda menggunakan method interface default dan statis.

Pada postingan terakhir ini, kita akan melihat annotations jenis, functional interfaces, dan bagaimana mengambil pendekatan yang lebih fungsional untuk pengolahan data dengan Stream Java 8 yang baru.

Saya juga akan menunjukan cara mengakses beberapa fitur Java 8 tambahan yang saat ini tidak didukung oleh platform Android, menggunakan libraries Joda-Time dan Three TenABP.

Type Annotations

Annotations membantu Anda menulis kode yang lebih kuat dan kurang rawan kesalahan, dengan menginformasikan alat pemeriksaan kode seperti Link tentang kesalahan yang harus mereka cari. Alat inspeksi ini kemudian akan memperingatkan Anda jika sepotong kode tidak sesuai dengan peraturan yang di tetapkan oleh annotations ini.

Annotations bukanlah fitur baru (sebenarnya, mereka berasal dari Java 5.0), namun di versi Java sebelumnya, hanya menerapkan annotations pada deklarasi.

Dengan dirilisnya Java 8, sekarang Anda dapat menggunakan annotations di manapun Anda menggunakan jenis, termasuk method receivers; class instance creation expressions; implementasi interface; generik dan arrays; spesifikasi throws dan implements clauses; dan tipe casting.

Frustasi, meskipun Java 8 memungkinkan untuk menggunakan annotations di lebih banyak lokasi daripada sebelumnya, namun tidak memberikan annotations yang spesifik untuk tipe.

Library Dukungan Annotations Android menyediakan akses ke beberapa annotations seperti @Nullable , @NonNull, dan annotations untuk memvalidasi resource seperti @DrawableRes , @DimenRes, @ColorRes , dan @StringRes . Namun, Anda mungkin juga ingin menggunakan alat analisis statis pada pihak ketiga, seperti Checker Framework , yang dikembangkan bersama dengan spesifikasi JSR 308 (spesifikasi Annotations pada Jenis Java). Framework ini menyediakan annotations tersendiri yang dapat diterapkan pada jenis, menambah sejumlah "pemeriksa" (annotation processors) yang terhubung ke proses komplikasi dan melakukan "cek" spesifik untuk setiap tipe annotation yang disertakan dalam Framework Checker.

Karena Tipe Annotations tidak mempengaruhi operasi runtime, Anda dapat menggunakan Java 8's Tipe Annotations dalam proyek Anda sambil tetap kompatibel dengan versi Java sebelumnya.

Stream API

Stream API menawarkan alternatif, "pipes-dan filter" pendekatan untuk pengolahan koleksi.

Sebelum Java 8, Anda memanipulasi koleksi secara manual, biasanya dengan iterasi selama pengumpulan dan operasi pada setiap elemen secara bergantian. Perulangan eksplisit ini membutuhkan banyak boilerplate, ditambah sulit untuk memahami struktur loop selama Anda mencapai badan loop.

API Stream memberi Anda cara untuk memproses data secara lebih efisien, dengan menjalankan data tunggal-terlepas dari jumlah data yang Anda proses, atau apakah Anda melakukan banyak perhitungan.

Di Java 8, setiap kelas yang mengimplementasikan java. util.Collection memiliki method stream yang bisa mengubah instancenya menjadi objek Stream . Misalnya jika Anda memiliki Array :

Kemudian Anda dapat mengubahnya menjadi Stream dengan yang berikut:

Stream API memproses data dengan membawa nilai dari sebuah source, melakui serangkaian langkah komputasi, yang dikenal sebagai stream pipeline. Stream pipeline terdiri dari:

  • Source, seperti fungsi Collection , array , atau generator function.
  • Operasi nol atau lebih antara "malas". Operasi perantara tidak mulai memproses elemen sampai Anda menjalankan operasi terminal-itulah sebabnya mereka dianggap malas. Misalnya, memanggil Stream.filter() pada sumber data hanya menyiapkan stream pipeline; Tidak ada penyaringan yang benar-benar terjadi sampai Anda memanggil operasi terminal. Hal ini memungkinkan untuk beberapa operasi bersama-sama dan kemudian melakukan semua perhitungan ini dalam satu data tunggal. Operasi perantara menghasilkan arus baru (misalnya,  filter  akan menghasilkan stream yang mengandung elemen yang disaring) tanpa memodifikasi source data, jadi Anda bebas menggunakan data asli di tempat lain di proyek Anda, atau beberapa streams dari source yang sama.
  • Operasi terminal, seperti Stream.forEach. Saat Anda menjalankan operasi terminal, semua operasi perantara Anda akan berjalan dan menghasilkan stream baru. Stream tidak mampu menyimpan elemen, jadi begitu Anda memanggil operasi terminal, stream itu dianggap "dikonsumsi" dan tidak lagi dapat digunakan. Jika Anda ingin meninjau kembali elemen stream, Anda harus membuat stream baru dari source data asli.

Membuat Stream

Ada berbagai cara mendapatkan stream dari sumber data, termasuk:

  • Stream.of( )  Membuat stream dari nilai individual:

  • IntSream.range( )  Membuat stream dari sejumlah angka:

  • Stream.iterate( ) Membuat stream dengan berulang kali menerapkan operator ke setiap elemen. Sebagai contoh, di sini kita membuat sebuah stream di mana setiap elemen meningkat nilainya satu-satu.

Mengubah Stream Dengan Operasi

Ada banyak operasi yang dapat Anda gunakan untuk melakukan perhitungan gaya fungsional di streams Anda. Pada bagian ini saya akan membahas beberapa stream yang paling sering digunakan.

Map

Operasi  map( ) mengambil ekpresi lambda sebagai satu-argument, dan gunakan ungkapan ini untuk mengubah bentuk atau jenis setiap elemen di stream. Contohnya memberi kita stream baru, di mana String telah diubah menjadi huruf besar.

Batas waktu

Operasi ini menetapkan batas pada ukuran stream. Misalnya, jika Anda ingin membuat stream baru yang berisi maksimal lima nilai, Anda akan menggunakan yang berikut ini:

Filter

Operasi filter(Predicate<T>) memungkinkan Anda menentukan kriteria pemfilteran menggunakan ekspresi lambda. Ekpresi lambda ini harus mengembalikan nilai boolean yang menentukan apakah setiap elemen harus disertakan dalam stream yang dihasilkan. Misalnya, jika Anda memiliki sederet string dan ingin menyaring string yang berisi kurang dari tiga karakter, Anda akan menggunakan yang berikut ini:

Sorted

Operasi ini mengurutkan elemen stream. Sebagai contoh, berikut ini mengembalikan sebuah stream angka yang disusun dalam urutan menaik.

Proses pararel

Semua operasi stream dapat dijalankan secara serial atau pararel, walaupun streamnya berurut kecuali jika Anda secara eksplisit menentukan yang lain. Sebagai contoh, berikut akan memproses setiap elemen satu per satu.

Untuk menjalankan stream secara pararel, Anda perlu secara eksplilsit menandai stream tersebut sebagai pararel, menggunakan method parallel():

Di bawah ini, stream pararel menggunakan Fork/Join Framework, sehingga jumlah benang yang tersedia harus sama dengan jumlah inti yang tersedia di CPU.

Kelemahan untuk parallel stream adalah bahwa inti yang berbeda dapat dilibatkan setiap kali kode dijalankan, sehingga Anda biasanya nendapatkan hasil yang berbeda dengan setiap eksekusi. Oleh karena itu, Anda hanya boleh menggunakan pararel stream saat urutan pemrosesan tidak penting, dan hindari aliran pararel saat melakukan operasi berdasarkan operasi, seperti findFirst( ).

Operasi Terminal

Anda mengumpulkan hasil dari stream menggunakan operasi terminal, yang selalu merupakan elemen terakhir dalam rangkaiian method stream, dan selalu mengembalikan sesuatu selain stream.

Ada beberapa jenis operasi terminal yang mengembalikan berbagai jenis data, namun di bagian ini kita akan melihat dua operasi terminal yang umum digunakan.

Mengumpulkan

The Collect operation mengumpulkan semua elemen yang diolah menjadi sebuah wadah, seperti  List or Set . Java 8 menyediakan kelas  utilitas,  Collectors , jadi Anda tidak kawatir menerapkan Collectors antarmuka , ditambah banyak factories collectors umum, termasuk tolist( ),  toSet ( ), dan toCollection ( )

Kode berikut ini menghasilkan  List  yang  berisi bentuk merah saja:

Sebagai alternalitif, Anda bisa mengumpulkan elemen yang disaring ini menjadi Set:

forEach

Operasi forEach() melakukan beberapa tindakan pada setiap elemen stream, menjadikannya setara dengan API Stream untuk setiap statement.

Jika Anda memiliki items list, Anda bisa menggunakannya forEach untuk menampilkan semua item yang disertakan dalam Daftar ini:

Dalam contoh diatas kita menggunakan ekpresi lambda, jadi mungkin untuk melakukan pekerjaan yang sama dengan kode yang lebih sedikit dengan menggunakan method reference.

Functional Interfaces

A funcional interface adalah antarmuka yang berisi method abstract yang tepat, yang dikenall sebagai method functional.

Konsep interfaces satu method yang tidak baru  -  Runnable , Comparator , Callable , dan OnCLickListener adalah semua contoh interfaces semacam ini, walaupun di versi Java sebelumnya mereka dikenal sebagai Single Abstrak Method Interfaces (SAM Interfaces)

Ini lebih sekedar perubahan nama sederhana, karena ada beberapa perbedaan penting dalam bagaimana Anda bekerja dengan interfaces functional (SAM) di Java 8, dibandingkan dengan versi sebelumnya.

Sebelum Java 8, Anda biasanya menginstal sebuah interfaces fungsional menggunakan penerapan kelas anonim yang besar. Sebagai contoh, disini kita membuat sebuah instance dari Runnable menggunakan kelas anonim:

Seperti yang kita lihat di bagian pertama, saat Anda memiliki single method interface, Anda dapat memberi contoh interface itu menggunakan ekspresi lambda, bukan kelas anonim Sekarang, kita dapat memperbarui peraturan ini: Anda dapat memberi instantiate functional interfaces, menggunakan ekpresi lambda. Sebagai contoh;

Java 8 juga memperkenalkan annotation @FunctionaLinterface  yang memungkinkan Anda menandai interface sebagai functional interface.

Untuk memastikan kompatibilitas dengan Java versi sebelumnya, annotation @FunctionaLinterfacev bersifat opsional; Namun, disarankan untuk membantu memastikan Anda menerapkan fuctional interfaces dengan benar.

Jika Anda mencoba menerapkan dua atau lebih di interfaces yang ditandai sebagai @FunctionaLinterface, maka compiler akan mengeluh bahwa ia telah menemukan beberapa method abstrak non-overriding. Misalnya, berikut ini tidak akan compile:

Dan, jika Anda mencoba mengkomlikasikan interfaces @functionInterface yang berisi metode jol, maka Anda akan menemukan No target method found error.

Functional Interfaces harus berisi method abstak yang tepat, namun karena method default dan statik tidak memiliki bentuk. Ini artinya Anda dapat menyertakan beberapa method default dan statik di interfaces, tandai sebagai @FunctionaLinterface, dan ini masih akan compile.

Java 8 juga menambahkan package java.util.function yang berisi banyak functional Interfaces. Ini layak meluangkan waktu untuk membiasakan diri dengan semua functional Interfaces, hanya agar Anda tahu persis apa yang tersedia tidak biasa.

JSR-310: API Tanggal dan Waktu Java Baru

Bekerja dengan tanggal dan waktu di Java tidak pernah terlalu mudah, seperti banyak API menghilangkan fungsi penting, seperti informasi zona waktu.

Java 8 memperkenalkan Tanggal dan Waktu API (JSR-310) baru yang bertujuan untuk mengatasi masalah ini, namun sayangnya pada saat penulisan API ini tidak didukung pada platform Android. Walaupun begitu, Anda dapat menggunakan beberapa fitur. Tanggal dan waktu baru diproyek Anda hari ini, menggunakan library pihak ke tiga.

Di bagian akhir ini, saya akan menunjukkan cara menyiapkan dan menggunakan dua library pihak ketiga yang populer sehingga memungkinkan untuk kenggunakan API Tanggal dan Waktu Java 8 di Android.

ThreeTen Android Backport

ThreeTen Android Backport (juga dikenal sebagai ThreeTenABP) adalah adaptasi dari proyek ThreeTen backport yang populer, yang memberikan implementasi JSR-310 untuk Java 6.0 dan Java 7.0. ThreeTenABP dirancang untuk menyediakan akses ke semua kelas Date and Time API (walaupun dengan nama paket yang berbeda) tanpa menambahkan sejumlah besar method ke proyek Android Anda.

Untuk mulai menggunakan library ini, buka file build.gradle tingkat modul Anda dan tambahkan ThreeTenABP sebagai dependency proyek:

Anda kemudian perlu menambahkan statement impor ThreeTenABP:

Dan menginisialisasi informasi ziba waktu dalam method Application.onCreate():

ThreeTenABP berisi dua jelas yang nenampilkan dua "jenis" infomasi waktu dan tanggal:

  • LocalDateTime, yang menyimpan waktu dan tanggal dalam format 2017-10-16T13: 17:57.138
  • ZonedDateTime, yaitu zona waktu yang mengetahui dan menyimpan infomasi tanggal dan waktu dalam format berikut: 2011-12-03T10:15:30+01:00[Eropa/Paris]

Untuk memberikan gambaran bagaimana Anda menggunakan library ini untuk nengambil informasi tanggal dan waktu, mari gunakan kelas LocaLDateTime untuk menampilkan tanggal dan waktu sekarang.

Display the date and time using the ThreeTen Android Backport libraryDisplay the date and time using the ThreeTen Android Backport libraryDisplay the date and time using the ThreeTen Android Backport library

Ini bukan cara paling user-frendly untuk menampilkan tanggal dan waktu! Untuk mengurai data mentah menjadi sesuatu yang lebih mudah dibaca manusia, Anda dapat gunakan kelas DateTimeFormatter dan set ke salah satu dari nilai berikut:  

  • BASIC_ISO_DATE. Format tanggal 2017-1016+01.00
  • ISO_LOCAL_DATE. Format tanggal seperti 2017-10-16
  • ISO_LOCAL_TIME. Fornat waktu seperti 14:58:43.242
  • ISO_LOCAL_DATE_TIME. Format tanggal dan waktu seperti 2017-10-16T14:58:09.616
  • ISO_OFFSET_DATE.  Fomat tanggal 2017-10-16+01.00
  • ISO_OFFSET_TIME. Format waktu seperti 14:58:56.218+01:00
  • ISO_OFFSET_DATE_TIME. Format tanggal dan waktu sebagai 2017-10-16T14:5836.758+01:00
  • ISO_ZONED_DATE_TIME. Format tanggal dan waktu sebagai 2017-10-16T14:51.324+01.00(Eropa/London)
  • ISO_INSTANT. Format tanggal dan waktu sebagai 2017-10-16T13:52:45.246Z
  • ISO_DATE. Format tanggal dan waktu 2017-289+01:00
  • ISO_TIME. Format waktu 14:58:40.945+01:00
  • ISO_DATE_TIME. Format tanggal dan waktu sebagai 2017-10-16T14:55:32.263+01:00(Eropa/London)
  • ISO_ORDINAL_DATE. Format tanggal 2017-280+01:00
  • ISO_WEEK_DATE. Fornat tanggal 2017-W42-1+01:00
  • RFC_1123_DATE_TIME.  Format tanggal dan waktu sebagai Mon, 16 Oktober 2017 14:58;43+01:00

Di sini, kami memperbarui aplikasi kami untuk nenampilkan tanggal dan waktu dengan format DateTimeFormatter.ISO_DATE      

Untuk menampilkan informasi ini dalam format yang berbeda, cukup ganti DateTimeFormatter.ISO_DATE  untuk nilai lain. Sebagai contoh:

Joda-Time

Sebelum Java 8, library Joda-Time dianggap sebagai library standar untuk menangani tanggal dan waktu di Java, sampai pada titik di mana Java Tanggal dan waktu API yang baru "benar-benar menarik banyak pengalaman dari proyek Joda-Time."

Sementara situs Joda-Time merekomendasikan agar pengguna bermigrasi ke Java 8 Tanggal dan Waktu sesegera mungkin, karena Android saat ini tidak mendukung API ini, Joda-Time masih merupakan pilihan yang tepat untuk pengembangan Android. Namun, perhatikan bahwa Joda-Time memang memiliki API besar dan memuat informasi zona waktu menggunakan resource JAR, yang keduanya dapat mempengaruhi kinerja aplikasi Anda.

Untuk mulai bekerja dengan library Joda-Time, buka file build.gradle tingkat modul Anda dan tambahkan yang berikut ini:

Library Joda-Time memiliki enam kelas dan waktu utama:

  • Instant: Merupakan titik di garis waktu; misalnya, Anda bisa mendapatkan tanggal dan waktu saat ini dengan menghubungi Istant.now( )
  • DateTime: Pengganti tujuan umum untuk kelas calendar JDK
  • LocalDate: Tanggal tanpa waktu, atau referensi ke zona waktu.
  • LocaLTime: Waktu tanpa tanggal atau referensi ke zona waktu, misalnya pukul 14:00:00
  • LocaLDateTime: Tanggal dan waktu lokal, masih tanpa informasi zona waktu.
  • ZonedDateTime: Tanggal dan waktu dengan zona waktu.

Mari kita lihat bagaimana Anda mencetak tanggal dan waktu menggunakan Joda-Time. Dalam contoh berikut, saya menggunakan kembali kode dari contoh ThreeTenABP kami, jadi untuk membuat sesuatu lebih menarik, saya juga menggunakan  withZone untuk mengubah tanggal dan waktu menjadi nilai ZonaDateTime.

Display the date and time using the Joda-Time libraryDisplay the date and time using the Joda-Time libraryDisplay the date and time using the Joda-Time library

Anda akan menemukan daftar lengkap zona waktu yang didukung di dokumentasi Joda-Time resmi.

Kesimpulan

Dalam posting ini, kami melihat bagaimana membuat kode yang lebih kuat menggunakan tipe annotations, dan mengeksplorasi pendekatan "pipes dan filters" untuk pemrosesan data dengan API stream Java 8 yang baru.

Kami juga melihat bagaimana interfaces telah berkembang di Java 8 dan bagaimana menggunakannya dalam kombinasi dengan fitur lain yang telah kami jelaskan dalam rangkaian ini, termasuk ekspresi lambda dan method interface statis.

Untuk menyelesaikan semuanya, saya menunjukkan kepada Anda bagaimana mengakses beberapa fitur Java 8 sebagai tambahan karena belum didukung oleh Android saat ini, menggunakan proyek Joda-Time dan ThreeTenABP.

Anda dapat mempelajari lebih lanjut tentang rilsan Java 8 di situs web Oracle.

Dan saat Anda berada di sini, lihat beberapa posting kami yang lain tentang pengembangan Java 8 dan Android!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.