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

Java 8 untuk Pembangunan Android: Stream dan Perpustakaan API Tarikh dan Masa

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

Malay (Melayu) translation by Muhammad Hasan (you can also view the original English article)

Dalam siri tiga bahagian ini, kami telah meneroka semua ciri utama Java 8 yang boleh anda gunakan pada projek Android anda hari ini

Dalam Cleaner Kod Dengan Expression Lambda , kami menumpukan pada pemotongan boilerplate dari projek anda menggunakan ekspresi lambda, maka dalam Default dan Static Methods , kita dapat melihat cara membuat ungkapan lambda ini lebih ringkas dengan menggabungkannya dengan rujukan metode. Kami juga mengulangi anotasi dan bagaimana untuk mengisytiharkan kaedah bukan abstrak pada antara muka anda menggunakan kaedah antara muka lalai dan statik.

Dalam jawatan terakhir ini, kami akan melihat jenis anotasi, antara muka berfungsi, dan cara untuk mengambil pendekatan yang lebih berfungsi untuk memproses data dengan Java 8 Stream yang baru.

Saya juga akan menunjukkan kepada anda bagaimana untuk mengakses beberapa ciri tambahan Java 8 yang pada masa ini tidak disokong oleh platform Android, menggunakan perpustakaan Joda-Time dan Tiga TenABP .

Taipkan Anotasi

Anotasi membantu anda menulis kod yang lebih kuat dan kurang rapi, dengan memberitahu anda tentang alat pemeriksa kod seperti pautan mengenai ralat yang perlu dicari. Alat pemeriksaan ini akan memberi amaran kepada anda jika sekeping kod tidak mematuhi peraturan yang ditetapkan oleh penjelasan ini.

Anotasi bukan ciri baru (sebenarnya, ia berasal dari Java 5.0), tetapi dalam versi Java yang sebelumnya, hanya digunakan penjelasan kepada perisytiharan.

Dengan melepaskan Java 8, kini anda boleh menggunakan anotasi di mana sahaja anda menggunakan jenis, termasuk penerima kaedah; ekspresi penciptaan contoh kelas; pelaksanaan antara muka; generik dan tatasusunan; spesifikasi throws dan implements klausa; dan jenis pemutus.

Kecewa, walaupun Java 8 memungkinkan menggunakan anotasi di lebih banyak lokasi daripada sebelumnya, tetapi tidak memberikan anotasi khusus jenis.

Perpustakaan Sokongan Anotasi Android menyediakan akses kepada beberapa anotasi seperti @Nullable , @NonNull , dan anotasi untuk mengesahkan sumber seperti @DrawableRes , @DimenRes , @ColorRes , dan @StringRes . Walau bagaimanapun, anda mungkin juga ingin menggunakan alat analisis statik pada pihak ketiga, seperti Rangka Kerja Pemeriksa , yang dikembangkan bersama dengan spesifikasi JSR 308 (spesifikasi Annotations dalam Jenis Java). Rangka kerja ini memberikan anotasi sendiri yang boleh digunakan untuk jenis, menambah beberapa "dam" (pemprosesan anotasi) yang disambungkan ke proses komplikasi dan melakukan "semakan" khusus untuk setiap jenis anotasi yang dimasukkan ke dalam Rangka Kerja Pemeriksa.

Kerana Anotasi Jenis tidak mempengaruhi operasi runtime, anda boleh menggunakan Anotasi Jenis Java 8 dalam projek anda sambil tetap serasi dengan versi Java sebelumnya.

Stream API

API Stream menawarkan pendekatan "paip-dan penapis" alternatif kepada pemprosesan pengumpulan.

Sebelum Java 8, anda memanipulasi koleksi secara manual, biasanya dengan lelaran semasa pengumpulan dan operasi setiap elemen secara bergantian. Gelung eksplisit ini memerlukan banyak boilerplate, ditambah dengan sukar untuk memahami struktur gelung selagi anda mencapai badan gelung.

API Stream memberikan anda cara untuk memproses data dengan lebih cekap, dengan menjalankan data tunggal - tanpa mengira jumlah data yang anda proses, atau sama ada anda melakukan banyak perhitungan.

Di Jawa 8, setiap kelas melaksanakan java. util.Collection java. util.Collection mempunyai kaedah stream yang dapat mengubah contohnya ke objek Stream . Contohnya jika anda mempunyai Array :

Kemudian anda boleh mengubahnya ke Stream dengan yang berikut:

API Stream memproses data dengan membawa nilai dari sumber, melalui satu siri langkah pengkomputeran, yang dikenali sebagai saluran paip sungai . Talian paip aliran terdiri daripada:

  • Sumber, seperti fungsi Collection , tatasusunan, atau penjana fungsi.
  • Operasi sifar atau lebih antara "malas". Operasi perantara tidak mula memproses unsur sehingga anda menjalankan operasi terminal - itulah sebabnya mereka dianggap malas. Sebagai contoh, memanggil Stream.filter () dalam sumber data hanya menyediakan saluran paip; Tiada penapisan benar-benar berlaku sehingga anda memanggil operasi terminal. Ini membolehkan beberapa operasi bersama-sama dan kemudian melakukan semua perhitungan dalam satu data. Operasi perantara menghasilkan arus baru (sebagai contoh, filter akan menghasilkan aliran yang mengandungi unsur yang ditapis) tanpa mengubah data sumber, jadi anda bebas menggunakan data asal di tempat lain dalam projek anda, atau beberapa aliran dari sumber yang sama.
  • Operasi terminal, seperti Stream.forEach . Apabila anda menjalankan operasi terminal, semua operasi perantara anda akan berjalan dan menghasilkan aliran baru. Stream tidak dapat menyimpan unsur-unsur, jadi sebaik sahaja anda memanggil operasi terminal aliran, Aliran tidak dapat menyimpan elemen, jadi sebaik sahaja anda menggunakan operasi terminal, aliran itu dianggap "dimakan" dan tidak dapat digunakan lagi. Jika anda mahu mengkaji semula unsur aliran, maka anda perlu menghasilkan aliran baru dari sumber data asal

Buat Stream

Terdapat pelbagai cara untuk mendapatkan aliran dari sumber data, termasuk:

  • Stream.of( ) Mencipta aliran daripada nilai individu:

  • IntSream.range( ) Mencipta aliran dari beberapa nombor:

  • Stream.iterate( ) Membuat aliran dengan berulang kali menerapkan pengendali ke setiap elemen. Sebagai contoh, di sini kita membuat aliran di mana setiap elemen meningkatkan nilai satu demi satu.

Tukar Stream dengan Operasi

Terdapat banyak operasi yang boleh anda gunakan untuk melakukan pengiraan gaya fungsian pada aliran anda. Dalam bahagian ini, saya akan membincangkan beberapa aliran yang sering digunakan.

Peta

Operasi map( ) mengambil ungkapan lambda sebagai argumen, dan menggunakan ungkapan ini untuk mengubah bentuk atau jenis setiap elemen dalam strim. Contohnya memberi kami aliran baru, di mana String telah ditukar kepada huruf besar.

Tarikh akhir

Operasi ini menetapkan had saiz strim. Sebagai contoh, jika anda ingin membuat aliran baru yang mengandungi maksimum lima nilai, anda akan menggunakan yang berikut:

Penapis 

Operasi filter(Predicate<T>) membolehkan anda menentukan kriteria penapisan menggunakan ekspresi lambda. Ungkapan lambda ini mesti mengembalikan nilai boolean yang menentukan sama ada setiap elemen mesti dimasukkan dalam aliran yang dihasilkan. Sebagai contoh, jika anda mempunyai rentetan rentetan dan mahu menapis rentetan yang mengandungi kurang daripada tiga aksara, anda akan menggunakan yang berikut:

Diisih

Operasi ini menyusun elemen aliran. Sebagai contoh, berikut mengembalikan aliran nombor yang disusun dalam urutan menaik :

Proses selari

Semua operasi aliran boleh dijalankan secara bersiri atau secara selari, walaupun aliran itu berurutan melainkan anda menyatakan dengan jelas satu lagi. Sebagai contoh, berikut akan memproses setiap elemen satu demi satu.

Untuk menjalankan aliran secara selari, anda perlu menandakan strim secara eksplisit selari dengan menggunakan kaedah parallel() :

Di bawah, aliran selari menggunakan Fork / Join Framework, jadi bilangan benang yang ada mestilah sama dengan bilangan teras yang terdapat pada CPU.

Kelemahan kepada aliran selari adalah bahawa teras yang berlainan mungkin terlibat setiap kali kod dilaksanakan, sehingga biasanya anda akan mendapat output yang berbeda dengan setiap pelaksanaan. Oleh itu, anda hanya perlu menggunakan aliran selari apabila pesanan pemprosesan tidak penting, dan elakkan aliran selari apabila melaksanakan operasi berasaskan pesanan, seperti findFirst ().

Operasi Terminal

Anda mengumpulkan hasil dari aliran menggunakan operasi terminal, yang selalu merupakan unsur terakhir dalam urutan turunan aliran, dan selalu mengembalikan sesuatu selain dari aliran.

Terdapat beberapa jenis operasi terminal yang mengembalikan pelbagai jenis data, tetapi dalam bahagian ini kita akan melihat dua operasi terminal yang biasa digunakan.

Kumpulkan

Operasi Collect mengumpul semua unsur yang diproses ke dalam bekas, seperti List atau Set . Java 8 menyediakan kelas utiliti, Collectors , jadi anda tidak bimbang tentang cara menggunakan antara muka Collectors , serta banyak kilang pengilang biasa, termasuk tolist( ) , toSet ( ) , toCollection ( )

Kod berikut menjana List yang mengandungi hanya borang merah:

Sebagai alternatif, anda boleh mengumpul elemen yang ditapis ke dalam Set :

forEach

Operasi forEach() menjalankan beberapa tindakan pada setiap unsur aliran, menjadikannya sama dengan API API untuk setiap pernyataan.

Jika anda mempunyai senarai items , anda boleh menggunakannya untuk setiap satu untuk memaparkan semua item yang termasuk dalam Daftar ini:

Dalam contoh di atas, kami menggunakan ungkapan lambda, jadi mungkin melakukan kerja yang sama dengan kod kurang menggunakan kaedah rujukan.

Antara muka fungsian

Antara muka funcion ialah antara muka yang mengandungi kaedah abstrak yang tepat, yang dikenali sebagai kaedah fungsional.

Konsep antara muka dengan kaedah yang bukan baru - Runnable , Comparator , OnCLickListener , dan OnCLickListener adalah semua contoh antaramuka seperti ini, meskipun dalam versi sebelumnya Java dikenal sebagai Single Abstract Method Interface (SAM Interface)

Konsep antara muka dengan kaedah yang bukan baru - Runnable , Comparator , OnCLickListener , dan OnCLickListener adalah semua contoh antaramuka seperti ini, meskipun dalam versi sebelumnya Java dikenal sebagai Single Abstract Method Interface (SAM Interface)

Sebelum Java 8, anda biasanya memasang antara muka berfungsi menggunakan aplikasi kelas anonim yang besar. Sebagai contoh, di sini kita membuat contoh Runnable menggunakan kelas tanpa nama:

Seperti yang kita lihat di bahagian pertama, apabila anda mempunyai antara muka kaedah tunggal, anda boleh memberikan contoh antara muka yang menggunakan ekspresi lambda, bukan kelas tanpa nama. Sekarang, kita boleh mengemas kini peraturan ini: Anda boleh instantiate interface berfungsi , menggunakan ekspresi lambda. Sebagai contoh;

Java 8 juga memperkenalkan anotasi @FunctionaLinterface yang membolehkan anda menandakan antara muka sebagai antara muka berfungsi.

Untuk memastikan keserasian dengan versi sebelumnya Java, anotasi @FunctionaLinterfacev adalah pilihan; Walau bagaimanapun, adalah disyorkan untuk membantu memastikan anda menggunakan antara muka fuktus dengan betul.

Sekiranya anda cuba memohon dua atau lebih antara muka yang ditandai sebagai @FunctionaLinterface , pengkompil akan mengeluh bahawa ia telah menemui beberapa kaedah bukan abstrak yang abstrak. Contohnya, perkara berikut tidak akan disusun:

Dan, jika anda cuba menggunakan interface @functionInterface yang mengandungi kaedah @functionInterface , anda akan mendapati ralat Tiada sasaran dijumpai .

Antaramuka Fungsi mesti mengandungi kaedah abstraksi yang betul, tetapi kerana kaedah lalai dan statik tidak mempunyai bentuk. Ini bermakna anda boleh menyertakan beberapa kaedah lalai dan statik di antara muka, menandakannya sebagai @FunctionaLinterface , dan ini masih akan disusun.

ava 8 juga menambah pakej java.util.function yang mengandungi banyak Antara muka berfungsi. Perlu mengambil masa untuk membiasakan diri dengan semua Antara muka berfungsi, supaya anda tahu apa yang tersedia adalah luar biasa.

JSR-310: API Tarikh dan Masa Jawa Baru

Bekerja dengan tarikh dan waktu di Jawa tidak pernah terlalu mudah, kerana API banyak menghilangkan fungsi penting, seperti maklumat zon waktu.

Java 8 memperkenalkan Tarikh dan Masa API yang baru (JSR-310) yang bertujuan untuk menyelesaikan masalah ini, tetapi malangnya pada masa menulis API ini tidak disokong pada platform Android. Walau bagaimanapun, anda boleh menggunakan beberapa ciri. Tarikh dan masa baru pada projek anda hari ini, gunakan perpustakaan pihak ketiga. 

pada akhir ini, saya akan menunjukkan kepada anda bagaimana untuk menyediakan dan menggunakan dua perpustakaan pihak ketiga yang popular supaya ia dapat menggunakan Java 8 Date and Time API pada Android.

TigaTen Android Backport

TigaTen Android Backport (juga dikenali sebagai ThreeTenABP) adalah penyesuaian projek backport TigaTen yang popular, yang menyediakan pelaksanaan JSR-310 untuk Java 6.0 dan Java 7.0. ThreeTenABP direka untuk memberikan akses kepada semua kelas API Tarikh dan Masa (walaupun dengan nama pakej yang berbeza) tanpa menambah sejumlah besar kaedah untuk projek Android anda.

Untuk mula menggunakan perpustakaan ini, buka tahap modul fail build.gradle anda dan tambahkan ThreeTenABP sebagai kebergantungan projek:

Anda kemudian perlu menambah penyataan import ThreeTenABP:

Dan inisikan maklumat ziba dalam kaedah Application.onCreate()

ThreeTenABP mengandungi dua jelas menunjukkan dua "jenis" maklumat masa dan tarikh:

  • LocalDateTime , yang menyimpan masa dan tarikh dalam format 2017-10-16T13: 17: 57.138
  • ZonedDateTime , yang merupakan zon waktu yang mengetahui dan menyimpan maklumat tarikh dan waktu dalam format berikut: 2011-12-03T10: 15: 30 + 01: 00 [Eropah / Paris]

Untuk memberikan idea bagaimana anda menggunakan perpustakaan ini untuk mendapatkan maklumat tarikh dan masa, mari kita gunakan kelas LocaLDateTime untuk memaparkan tarikh dan masa semasa.

Display the date and time using the ThreeTen Android Backport library

Ini bukan cara yang paling bergantung kepada pengguna untuk memaparkan tarikh dan masa! Untuk menghuraikan data mentah menjadi sesuatu yang lebih mudah dibaca oleh manusia, anda boleh menggunakan kelas DateTimeFormatter dan tetapkannya kepada salah satu nilai berikut:

  • BASIC_ISO_DATE. Format untuk tarikh 2017-1016 + 01.00 
  • ISO_LOCAL_DATE . Format tarikh seperti 2017-10-16
  • ISO_LOCAL_TIME . Jatuh masa seperti 14: 58: 43,242 ISO_LOCAL_DATE_TIME . Format tarikh dan masa seperti
  • ISO_LOCAL_DATE_TIME . Format tarikh dan masa seperti 2017-10-16T14: 58: 09616
  • ISO_LOCAL_DATE_TIME . Format tarikh dan masa seperti 2017-10-16 + 01.00
  • ISO_OFFSET_TIME . Format masa seperti 14: 58: 56,218 + 1:00
  • ISO_OFFSET_DATE_TIME . Format tarikh dan masa sebagai 2017-10-16T14: 5836,758 + 01:00
  • ISO_ZONED_DATE_TIME . Format tarikh dan masa sebagai 2017-10-16T14: 51,324 + 01.00 (Eropah / London)
  • ISO_INSTANT . Format tarikh dan masa sebagai 2017-10-16T13: 52: 45.246Z
  • ISO_DATE . Format tarikh dan masa 2017-289 + 01:00
  • ISO_TIME . Format masa 14: 58: 40,945 + 01:00
  • ISO_DATE_TIME . Format tarikh dan masa sebagai 2017-10-16T14: 55: 32,263 + 01:00 (Eropah / London)
  • ISO_ORDINAL_DATE . Format untuk 2017-280 + 01:00
  • ISO_WEEK_DATE. Fornat bertarikh 2017-W42-1 + 01:00
  • RFC_1123_DATE_TIME . Format tarikh dan masa sebagai Isnin, 16 Oktober 2017 14:58; 43 + 01:00

Di sini, kami mengemas kini permohonan kami untuk memaparkan tarikh dan masa dalam format DateTimeFormatter.ISO_DATE

Untuk memaparkan maklumat ini dalam format yang berbeza, hanya ganti DateTimeFormatter.ISO_DATE untuk nilai lain. Sebagai contoh:

Joda-Time

Sebelum Java 8, perpustakaan Joda-Time dianggap sebagai perpustakaan standard untuk mengendalikan tarikh dan masa di Jawa, sehingga titik Java Date dan API masa baru "benar-benar menarik banyak pengalaman dari projek Joda-Masa."

Walaupun tapak Joda-Masa mengesyorkan bahawa pengguna berhijrah ke Java 8 Tarikh dan Masa secepat mungkin, kerana Android saat ini tidak menyokong API ini, Joda-Time masih merupakan pilihan yang tepat untuk pembangunan Android. Walau bagaimanapun, ambil perhatian bahawa Joda-Time mempunyai API yang besar dan mengandungi maklumat zon masa menggunakan sumber JAR, kedua-duanya dapat menjejaskan prestasi aplikasi anda.

Untuk mula bekerja dengan perpustakaan Joda-Masa, buka fail build.gradle modul anda dan tambah yang berikut:

Perpustakaan Joda-Time mempunyai enam kelas dan masa utama: Instant :

  • Instant : Adalah titik pada garis masa; sebagai contoh, anda boleh mendapatkan tarikh dan masa semasa dengan menghubungi Istant.now( )
  • DateTime : Gantikan tujuan umum untuk kelas calendar JDK LocalDate :
  • LocaLTime : Masa tanpa tarikh atau rujukan ke zon waktu,
  • LocaLTime : Masa tanpa tarikh atau rujukan ke zon waktu, seperti 14:00:00
  • LocaLDateTime : Tarikh dan masa tempatan, masih tanpa maklumat zon masa.
  • ZonedDateTime : Tarikh dan masa dengan zon masa.

Mari lihat bagaimana anda mencetak tarikh dan masa menggunakan Joda-Time. Dalam contoh berikut, saya menggunakan semula kod dari contoh TigaTenABP kami, jadi untuk menjadikan perkara lebih menarik, saya juga menggunakan withZone untuk menukar tarikh dan masa kepada nilai ZonaDateTime .

Display the date and time using the Joda-Time library

Anda akan mendapati senarai lengkap zon masa yang disokong dalam dokumentasi Joda-Masa rasmi .

Kesimpulannya

Dalam siaran ini, kita melihat bagaimana untuk membuat kod yang lebih kuat menggunakan jenis anotasi, dan meneroka pendekatan untuk "paip dan penapis" untuk memproses data dengan aliran Java 8 API baru.

Kami juga melihat bagaimana antara muka dibangunkan di Java 8 dan bagaimana menggunakannya dalam kombinasi dengan ciri-ciri lain yang telah kita jelaskan dalam siri ini, termasuk ekspresi lambda dan kaedah antara muka statik.

Untuk mendapatkan semua yang dilakukan, saya menunjukkan kepada anda bagaimana untuk mengakses sebahagian daripada ciri-ciri Java 8 sebagai tambahan kerana mereka tidak disokong oleh Android pada masa ini, menggunakan projek Joda-Time dan ThreeTenABP.

Anda boleh mengetahui lebih lanjut mengenai melayari Java 8 di laman web Oracle.

Dan apabila anda di sini, lihat beberapa jawatan kami yang lain mengenai membangun Java 8 dan Android!

Advertisement
Advertisement
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.