Akan ada banyak objek dalam pengembangan proyek yang sebenarnya. Java menyediakan kerangka kerja koleksi untuk menyelesaikan masalah tersebut Kelas berada dalam paket java.util, dan daftar 1 menjelaskan hubungan antara kelas pengumpulan.
Listing 1. Hubungan antara kelas pengumpulan
Koleksi
├List
│├Linkedlist
│laarraylist
│orvektor
│ Kstack
└set
Peta
Bhashtable
Phashmap
Sweakhashmap
Antarmuka koleksi
Antarmuka koleksi
Koleksi adalah antarmuka koleksi paling dasar. Beberapa koleksi memungkinkan elemen yang sama dan mendukung elemen penyortiran, sementara yang lain tidak berfungsi. JDK tidak menyediakan kelas yang diwarisi langsung dari koleksi. Semua kelas yang mengimplementasikan antarmuka koleksi harus menyediakan dua konstruktor standar. Konstruktor terakhir memungkinkan pengguna untuk menyalin koleksi.
Bagaimana cara mengulangi setiap elemen dalam koleksi?
Terlepas dari jenis koleksi yang sebenarnya, ia mendukung metode iterator (). Penggunaan khas adalah sebagai berikut:
Iterator it = collection.iterator ();
Dua antarmuka antarmuka koleksi adalah daftar dan diatur.
Metode utama yang disediakan oleh antarmuka koleksi:
1. Boolean Tambahkan (objek o) Tambahkan objek ke koleksi;
2. Boolean hapus (objek o) Hapus objek yang ditentukan;
3. Int size () mengembalikan jumlah elemen dalam koleksi saat ini;
4. Boolean berisi (objek o) Temukan apakah ada objek yang ditentukan dalam set;
5. boolean isempty () Tentukan apakah set kosong;
6. iterator iterator () mengembalikan iterator;
7. Boolean mengandung semua (Koleksi c) Temukan apakah ada elemen di set C di set;
8. Boolean Addall (Koleksi C) menambahkan semua elemen dalam koleksi C ke koleksi;
9. void clear () Hapus semua elemen dalam set;
10. void removeall (koleksi c) hapus elemen dalam set c -collection dari koleksi;
11. void retainall (koleksi c) hapus elemen yang tidak termasuk dalam koleksi C dari koleksi.
Daftar antarmuka
Daftar adalah koleksi tertib yang dapat secara akurat mengontrol posisi setiap penyisipan elemen dengan antarmuka ini. Pengguna dapat menggunakan indeks (posisi elemen dalam daftar, mirip dengan penawaran array) untuk mengakses elemen dalam daftar, yang mirip dengan array Java. Berbeda dengan set yang akan disebutkan di bawah ini, daftar memungkinkan elemen yang sama.
Selain metode iterator () yang diperlukan untuk antarmuka koleksi, Daftar juga menyediakan metode ListIterator () untuk mengembalikan antarmuka Listotrator. Dibandingkan dengan antarmuka iterator standar, Listotrator memiliki beberapa metode seperti ADD (), memungkinkan fungsi seperti menambahkan, menghapus, mengatur elemen, traversal maju atau mundur. Kelas yang umum digunakan untuk mengimplementasikan antarmuka daftar termasuk LinkedList, ArrayList, Vector dan Stack.
Metode utama yang disediakan oleh antarmuka daftar:
1. Void add (indeks int, elemen objek) menambahkan objek di lokasi yang ditentukan;
2. Boolean Addall (int magang, koleksi c) menambahkan elemen set C ke posisi yang ditentukan;
3. Object Get (int index) Mengembalikan elemen yang ditentukan dalam posisi yang ditunjuk dalam daftar;
4. Indexof (Objek O) Mengembalikan posisi elemen pertama o;
5. Objek RemestInIn (indeks int) Hapus elemen dari posisi yang ditentukan;
6. Set Object (int indexex, elemen objek) Ganti elemen pada indeks posisi elemen elemen untuk mengembalikan elemen yang dapat diganti.
Antarmuka peta
Peta tidak mewarisi antarmuka Colleg. Peta menyediakan pemetaan dari kunci ke nilai. Antarmuka peta menyediakan 3 set tampilan.
Metode utama yang disediakan oleh peta:
1. Boolean Equals (Objek O) Objek Perbandingan;
2. Boolean hapus (objek o) hapus objek;
3. Put (Kunci Objek, Nilai Objek) Tambahkan Kunci dan Nilai.
Antarmuka AcomesAccess
Antarmuka RandomAccess adalah antarmuka logo, yang tidak menyediakan metode apa pun itu sendiri. Tujuan utama antarmuka ini adalah untuk mengidentifikasi implementasi daftar yang dapat mendukung akses cepat dan acak. Implementasi daftar berbasis array apa pun mengimplementasikan antarmuka RaoDomAccess, sedangkan implementasi berbasis daftar yang ditautkan tidak. Karena hanya array yang dapat melakukan akses acak yang cepat, akses acak ke daftar yang ditautkan perlu dilalui oleh daftar tertaut. Oleh karena itu, keuntungan antarmuka ini adalah bahwa dalam aplikasi, Anda dapat mengetahui apakah objek daftar yang sedang diproses dapat melakukan akses cepat dan acak, sehingga dapat melakukan operasi yang berbeda untuk daftar yang berbeda untuk meningkatkan kinerja program.
Perkenalan
Kelas LinkedList
LinkedList mengimplementasikan antarmuka daftar dan memungkinkan elemen nol. Selain itu, LinkedList menyediakan tambahan, hapus, masukkan, dan metode lain untuk mengoperasikan data di First atau Tail of LinkedList. Operasi ini membuat LinkedList dapat digunakan sebagai tumpukan, antrian (antrian) atau dua antrian. Harap dicatat bahwa LinkedList tidak memiliki metode sinkronisasi. Salah satu solusi adalah membuat daftar sinkron saat membuat daftar.
Daftar daftar = collections.synchronizedList (LinkedList baru (...));
Kelas ArrayList
ArrayList mengimplementasikan array ukuran variabel. Ini memungkinkan semua elemen, termasuk nol. Ukuran, ISEMPTY, GET, SET, dan metode lain berjalan, tetapi overhead Metode Tambah adalah konstan dari berbagi.
Setiap contoh arraylist memiliki kapasitas (kapasitas) untuk menyimpan ukuran array elemen penyimpanan. Ketika sejumlah besar elemen perlu dimasukkan, Anda dapat menghubungi metode penipuan sebelum dimasukkan untuk meningkatkan kapasitas arraylist untuk meningkatkan efisiensi penyisipan. Seperti LinkedList, ArrayList juga merupakan thread -not -synchronized (tidak disinkronkan).
Metode utama yang disediakan oleh ArrayList:
1. Boolean Add (Object O) menambahkan elemen yang ditentukan ke akhir daftar;
2. Boolean Add (int indexex, elemen objek) untuk menentukan posisi untuk menambahkan elemen yang ditentukan dalam daftar;
3. Boolean Addall (Koleksi C) menambahkan set yang ditentukan ke akhir daftar;
4. Boolean Addall (int Interleg, Collection c) Tambahkan koleksi yang ditentukan di lokasi yang ditentukan dalam daftar;
5. Boolean Clear () Hapus semua elemen dalam daftar;
6. Boolean Clone () kembali ke salinan daftar daftar;
7. Boolean berisi (objek o) menentukan apakah itu berisi elemen dalam daftar;
8. Boolean Ensurecapacity (int m) meningkatkan kapasitas daftar.
9. Objek Dapatkan (INT INDEX) Mengembalikan elemen yang ditentukan dalam daftar dalam daftar;
10. INDEXOF (Objek Elem) Dalam daftar menemukan penawaran elemen yang ditentukan;
11. int size () mengembalikan jumlah elemen dari daftar saat ini.
Kelas Vektor
Vektor sangat mirip dengan ArrayList, perbedaannya adalah bahwa vektor disinkronkan oleh utas. Iterator yang dibuat oleh vektor, meskipun iterator yang dibuat oleh arrayList adalah port yang sama, karena vektor disinkronkan, ketika satu iterator dibuat dan digunakan, utas lainnya mengubah status vektor (misalnya, menambahkan atau menghapus sebagian dari beberapa elemen negara), ketika metode iterator dipanggil, ConcurrentModificationException akan dibuang, sehingga pengecualian harus ditangkap.
Kelas tumpukan
Tumpukan diwarisi dari vektor dan menyadari tumpukan yang kemudian maju. Stack menyediakan 5 metode tambahan untuk vektor untuk digunakan sebagai tumpukan. Selain metode dorongan dan pop dasar, ada juga metode Peek untuk mendapatkan elemen bagian atas tumpukan. tumpukan. Perhatikan bahwa setelah Stack baru saja dibuat, itu adalah tumpukan kosong.
Setel kelas
Set adalah koleksi tanpa elemen berulang, yaitu, dua elemen E1 dan E2 memiliki e1.equals (e2) = false. Ada elemen nol di sebagian besar set. Jelas, konstruktor set memiliki kondisi kendala, dan input parameter pengumpulan tidak dapat menyertakan elemen duplikat. Harap dicatat bahwa Anda harus mengoperasikan objek variabel dengan hati -hati.
Kelas hashtable
Hashtable mewarisi antarmuka peta dan mengimplementasikan tabel hash berdasarkan pemetaan nilai kunci. Objek non-nol dapat digunakan sebagai kunci atau nilai. Tambahkan data untuk menggunakan put (kunci, nilai), dan ambil data untuk menggunakan GET (kunci).
Hashtable menyesuaikan kinerja melalui dua parameter kapasitas awal dan faktor beban. Faktor beban default 0,75 lebih baik mencapai keseimbangan waktu dan ruang. Meningkatkan faktor beban dapat menghemat ruang tetapi waktu pencarian yang sesuai akan meningkat, yang akan mempengaruhi operasi seperti Get and Put. Gunakan contoh sederhana hashtable untuk menempatkan tiga angka 1, 2, dan 3 di hashtable.
Daftar 2. Contoh Hashtable
Hashtable number = hashtable baru (); number.put ("satu", integer baru (1)); number.put ("dua", bilangan bulat baru (2)); number.put ("tiga", bilangan bulat baru (3 );
Jika kita perlu mengambil angka, seperti 2, kita dapat menggunakan kunci yang sesuai untuk mengeluarkannya, dan kode ditampilkan di Daftar 3.
Daftar 3. Baca data dari Hastable
Integer n = (integer) numbers.get ("dua");
Karena objek kunci akan ditentukan dengan menghitung fungsi distribusinya untuk menentukan posisi nilai yang sesuai, objek apa pun sebagai kunci harus mengimplementasikan kode hashcode dan sama dengan metode. HashCode dan Equals Metode mewarisi objek root. = Benar, kode hash mereka harus sama, tetapi jika kedua objek itu berbeda, kode hash mereka tidak selalu berbeda. Metode hashcode () yang dapat mempercepat pengoperasian tabel hash.
Jika objek yang sama memiliki kode hash yang berbeda, akan ada hasil yang tidak terduga untuk pengoperasian tabel hash (berharap untuk mengembalikan nol). Alih -alih hanya menulis salah satunya.
Kelas hashmap
HashMap mirip dengan Hashtable. Namun, ketika hashmap dianggap sebagai pengumpulan (metode nilai () dapat dikembalikan), itu sebanding dengan overhead waktu sub -operasi yang berulang dan kapasitas hashmap. Oleh karena itu, jika kinerja operasi iterasi sangat penting, jangan atur kapasitas inisialisasi hashmap terlalu tinggi, atau set terlalu rendah dalam parameter faktor beban.
Kelas WeakHashMap
Lemarihashmap adalah hashmap yang lebih baik yang "referensi lemah" untuk kunci.
Latihan Kelas Koleksi
ArrayList, Vector, dan LinkedList semuanya diimplementasikan dari AbstractList, dan AbstractList secara langsung mengimplementasikan antarmuka daftar dan diperluas dari AbstarctCollection. ArrayList dan Vector menggunakan array untuk diterapkan. LinkedList menggunakan struktur data tertaut dua arah, yang dihubungkan oleh serangkaian item tabel.
Ketika permintaan ArrayList untuk kapasitas melebihi ukuran array saat ini, perlu diperluas. Selama proses ekspansi kapasitas, sejumlah besar operasi replikasi array akan dilakukan, dan ketika array direplikasi, metode System.ArrayCopy () akhirnya akan dipanggil. Karena LinkedList menggunakan struktur daftar yang ditautkan, ia tidak perlu mempertahankan ukuran kapasitas. Karena kesinambungan array, ketika elemen selalu meningkat pada akhirnya, ekspansi array dan replikasi array hanya dapat dihasilkan ketika ruang tidak cukup.
ArrayList didasarkan pada array, dan array adalah ruang memori yang berkelanjutan. LinkedList tidak mengurangi kinerja karena memasukkan data.
Setiap elemen arraylist yang efektif harus direorganisasi setelah menghapus operasi, dan semakin tinggi posisi posisi elemen yang dihapus, semakin besar overhead selama reorganisasi array. LinkedList perlu menghapus data perantara untuk setengah daftar.
Daftar 4. Daftar ArrayList dan LinkedList Gunakan Kode
Impor Java.util.arraylist; = Objek baru (); untuk (int i = 0; i <5000000; i ++) {list.add (obj);} Long End = System.currentTimeMillis (); m. (); 0, Obj2); 1000; i ++) {list1.add (obj1);} end = System.currenttTimemillis (); System.currenttTimemillis (); ;}}
Daftar 5. Jalankan Output
639129669690015
HashMap adalah membuat algoritma utama, dan kemudian memetakan nilai hash ke alamat memori untuk secara langsung mendapatkan data yang sesuai dengan kunci. Dalam HashMap, struktur data yang mendasarinya menggunakan array, alamat memori yang disebut SO adalah indeks label array. Kinerja tinggi Hashmap membutuhkan poin -poin berikut:
1. Algoritma hash harus efisien;
2. Algoritma dari nilai hash ke alamat memori (indeks array) cepat;
3. Menurut alamat memori (indeks array), Anda dapat secara langsung mendapatkan nilai yang sesuai.
HashMap sebenarnya adalah array dari daftar yang ditautkan. Seperti disebutkan sebelumnya, mekanisme implementasi berdasarkan metode daftar tertaut berdasarkan hashmap, selama metode hashcode () dan hash () dicapai cukup untuk mengurangi terjadinya konflik sebanyak mungkin, maka operasi hashmap adalah Hampir setara dengan akses acak ke array array. Namun, jika metode hashcode () atau hash () dicapai dengan buruk, dalam kasus sejumlah besar konflik, hashmap sebenarnya terdegradasi ke dalam beberapa daftar terkait, yang setara dengan daftar yang ditautkan untuk pengoperasian hashmap Kali ini, kinerjanya sangat buruk.
Kerugian fungsional dari hashmap adalah gangguannya, yang disimpan dalam elemen -elemen dalam hashmap. Jika Anda ingin menjaga pesanan input, Anda dapat menggunakan LinkedHashMap sebagai gantinya.
LinkedHashMap mewarisi dari hashmap dan memiliki efisiensi tinggi.
HashMap dapat mengoperasikan put () dan mendapatkan () secepat algoritma hash. TreeMap menyediakan implementasi peta yang sama sekali berbeda. Dalam hal fungsi, TreeMap memiliki fitur yang lebih kuat daripada HashMap. Kinerja TreeMap sedikit lebih rendah dari hashmap. Jika Anda perlu mengurutkan elemen dalam pengembangan, Anda tidak dapat mengimplementasikan fungsi ini dengan HashMap. LinkedHashMap didasarkan pada urutan elemen yang memasuki koleksi atau urutan berurutan yang diakses.
LinkedHashMap diurutkan sesuai dengan urutan peningkatan atau akses elemen, sementara TreeMap diurutkan sesuai dengan kunci elemen.
Listing 6 menunjukkan bahwa kode menunjukkan urutan logika bisnis menggunakan TreeMap.
Listing 6. TreeMap mengimplementasikan penyortiran
Impor Java.util.iterator; nama; ini. (O.score> this.score) {return -1;} return 0;} @Overridepublic String toString () {StringBuffer SB = New StringBuffer (); ; (); Siswa S1 = Siswa Baru ("1", 100); Siswa S2 = Siswa Baru ("2", 99); Siswa S3 = Siswa Baru ("3", 97); Siswa S4 = Siswa Baru ("4 ", 91); Map.put (S1, StudentDetailinfo baru (S1)); Map.put (S2, StudentDetailInfo baru (S2)); Map.put (S3, StudentDetailinfo baru (S3)); S4, StudentDetailinfo baru (S4 )); next (); System.out.println (Key+"->"+Map.get (Key));} System.out.println ("" Submap end "); // MAP1 = ((TimeMap) peta). Headmap (s1); (Key));} System.out.println ("Submap End"); // Cetak skor MAP1 = ((TREEMAP) .tailmap (S1); untuk (iterator iterator = map1.keyset (). iterator.hasnext () ;) {Student key = (siswa) itrator (Siswa S) {this.s = s;}@ounridepublic string toString () {return s.name + "informasi detail";}}
Daftar 7. Jalankan Output
Nama: 4 Skor: 91-> 4's InformationName Detail: 3 Skor: 97-> 3's Detail Informationsubmap Endname: 4 Skor: 91-> 4's InformationName: 3 Skor: 97-> 3 'S Detail Informasi: 2 Skor: 99- > Informationsubmap Detail 2 Nama Akhir: 1 Skor: 100-> Detail 1 Informationsubmap End
Weakhashmap ditandai dengan sendirinya bahwa jika tidak ada cither lain di kunci ini kecuali untuk kutipannya, maka peta ini akan secara otomatis membuang nilainya. Seperti yang ditunjukkan dalam Listing 8, kode ini menunjukkan dua objek peta, satu hashmap, dan yang lainnya adalah Lemah Hash. Null, mereka menunjuk ke NULL. Alasan untuk situasi ini adalah bahwa untuk objek A, ketika hashmap dihapus dan a ke nol, selain lemah yang melemah, tidak ada pointer ke A kecuali A walaupun menunjuk ke nol, ada pointer yang menunjuk ke B dalam hashmap, jadi lemahhashmapapapapapmap, ada pointer akan mempertahankan objek B.
Daftar 8. WeakHashMap Contoh Kode
Impor Java.util.hashmap; String (a "); , B, b, b, b, b, b, b, b, b, b, b, b, b, b, "bbb"); , BBB "); .entry en = (MAP.ENTRY) IZEXT (); Iterator (); +En.getValue ());
Listing 9. Jalankan output
Peta: B: BBBWeakMap: B: BBB
Weakhashmap terutama mencapai tujuan menghapus entri internal yang tidak digunakan melalui Expungestaleentries, sehingga mencapai tujuan secara otomatis melepaskan memori. Pada dasarnya, selama konten Lemahhashmap diakses, fungsi ini akan dipanggil untuk mencapai entri internal yang tidak lagi dirujuk. Tetapi jika Anda telah menjadi orang yang lemah, dan sebelum GC, Anda belum pernah mengunjungi The WeakHashMap, bukankah tidak terbatas untuk melepaskan memori?
DAFTAR 10. WeakHashMaptest1
Impor Java.util.arraylist; ] [] >> MAPS = Daftar Array baru <LemarihashMap <byte [] [], byte [] [] >> (); byte [] []> D = New WeakHashMap <byte [] [], byte [] []> (); .add (d);
Jangan ubah Parameter JVM Daftar 10 yang ditunjukkan dalam daftar operasi.
Daftar 11. Jalankan Output
241242243Excetion di utas "utama" java.lang.outofmemoryError: java heap spaceat weasthashmaptest1.main (lemahanhashmapst1.java:10)
Benar saja, Weakhashmap tidak secara otomatis melepaskan memori yang tidak perlu saat ini. Kode yang ditampilkan dalam Listing 12 tidak akan memiliki overflow memori.
Daftar 12. WeakhashMaptest2
Impor Java.util.arraylist; ] [] >> MAPS = Daftar Array baru <LemarihashMap <byte [] [], byte [] [] >> (); byte [] []> D = New WeakHashMap <byte [] [], byte [] []> (); .add (d); .Get (j) .size ());}}}}
Hasil operasi menemukan bahwa output tes normal, dan masalah overflow memori tidak lagi terjadi.
Secara umum, Lemah yang lemah bukanlah objek yang tidak digunakan di dalam jika Anda melakukan sesuatu, tetapi lepaskan objek internal yang tidak digunakan saat Anda mengaksesnya.
WeakhashMap mengimplementasikan referensi yang lemah karena entri <k, v> diwarisi dari lemahan refreferensi <K>.
Dalam definisi kelas dan konstruktor entri Lemari $ <K, V>, itu ditampilkan dalam daftar 13.
Daftar 13. Definisi Kelas Weakhashmap
Entri kelas statis pribadi <K, V> memperluas Lemah Referensi <K> mengimplementasikan MAP.entry <K, V> entri (Kunci K, nilai V, ReferenceQueue <K> antrian, int hash, entri <k, v> berikutnya) {Super (Kunci, antrian);
Harap dicatat bahwa ia membangun pernyataan ayah -kelas: "Super (kunci, antrian);"; Dalam System.gc (), array byte pada kunci didaur ulang, dan nilai tetap (nilai sangat terkait dengan entri, entri dikaitkan dalam MAP, dan MAP dikaitkan dalam ArrayList).
Setiap kali saya memiliki lemah baru setiap kali, setelah operasi put, meskipun GC mendaur ulang array byte dalam kunci refreferensi lemah, dan memberi tahu peristiwa tersebut ke ReferenceQueue, tidak ada tindakan yang sesuai untuk memicu lemah yang lemah untuk menangani referensi yang beres. Kunci masih ada di lemah yang lemah, dan nilainya yang sesuai juga ada.
Kapan nilainya dibersihkan? ? Periksa Kode Sumber Weakhashmap. Oleh karena itu, efeknya adalah bahwa kunci dibersihkan ketika GC, dan nilai mengunjungi Lemah Lemah setelah kunci dibersihkan.
Kelas WeakHashMap tidak disinkronkan. Oleh karena itu, apakah itu dalam pemetaan atau di luar pemetaan, kunci secara otomatis dihapus hanya setelah pendaur ulang sampah menghapus referensi yang lemah ke kunci tertentu. Perlu dicatat bahwa objek nilai dalam weakhashmap disimpan oleh ketertarikan umum. Oleh karena itu, Anda harus berhati -hati untuk memastikan bahwa objek nilai tidak akan secara langsung atau tidak langsung merujuk kuncinya sendiri, karena ini akan mencegah ketegangan dari dibuang. Perhatikan bahwa objek nilai secara tidak langsung dapat mengutip kunci yang sesuai melalui lemah yang melemah itu sendiri, yang berarti bahwa objek nilai tertentu dapat dirujuk secara kuat oleh objek kunci lainnya, dan objek nilai yang terkait dengan objek kunci beralih ke yang pertama untuk referensi yang pertama satu.
Salah satu cara untuk menangani masalah ini adalah dengan mengemas nilai itu sendiri di Lemah Lemah sebelum dimasukkan, seperti: M.Put (Kunci, Referensi Lemah Baru (Nilai)), dan kemudian gunakan Diseksi. "Perangkat pendukung gagal dengan cepat. Setelah perangkat iteratif dibuat, jika pemetaan dimodifikasi dari struktur, kecuali jika iterator sendiri menghapus atau menambahkan metode, iterator akan dimodifikasi kapan saja dan dengan cara apa pun, dan iterator akan Lemparkan ConcurrentModificationException. Oleh karena itu, dalam menghadapi modifikasi konkurensi, iterator dengan cepat gagal sepenuhnya, daripada risiko pada perilaku tidak pasti sewenang -wenang setiap saat di masa depan.
Perhatikan bahwa kami tidak dapat memastikan bahwa iterator gagal.
Untuk meringkas kode pengantar dan instance dalam komprehensif sebelumnya, kita dapat mengetahui bahwa jika itu melibatkan tumpukan, antrian, dll., Kita harus mempertimbangkan untuk menggunakan daftar. Untuk operasi seperti elemen penyisipan dan penghapusan cepat, LinkedList harus digunakan. Jika Anda perlu mengakses elemen dengan cepat, Anda harus menggunakan ArrayList. Jika program ini dilakukan dalam satu lingkungan yang beracun atau akses hanya di satu utas, mempertimbangkan kelas yang tidak disinkronkan, itu efisien. Jika beberapa utas dapat mengoperasikan kelas secara bersamaan, kelas sinkron harus digunakan. Berikan perhatian khusus pada pengoperasian tabel hash, dan objek setara dan kode hash sebagai kunci adalah untuk menulis dengan benar metode setara dan kode hashcode. Cobalah untuk mengembalikan antarmuka alih -alih tipe aktual, seperti daftar kembali alih -alih arraylist, sehingga jika arraylist perlu diganti dengan LinkedList di masa depan, kode klien tidak perlu berubah.
Artikel ini hanya untuk berbagi tingkat aplikasi.