-
Mengonversi array menjadi ArrayList .
Untuk mengonversi array menjadi ArrayList , pengembang sering menggunakan metode ini:
List<String> list = Arrays.asList(arr);
Arrays.asList()
akan mengembalikan objek kelasArrayList
yang merupakan kelas statis pribadi internal kelas(private static class)
,Arrays
dan ini bukan kelasjava.util.ArrayList.
. Kelasjava.util.Arrays.ArrayList
berisi metodeset()
,,, tetapi tidak berisi metode apa pun untuk menambahkan elemen, ukurannya tetap . Untuk membuat yang asli , lakukan ini:get()
contains()
java.util.ArrayList
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));
Konstruktor kelas
java.util.ArrayList
dapat mengambil parameter semua objek yang mengimplementasikan antarmukaCollection
, yang implementasinya diwarisi oleh kelasjava.util.Arrays.ArrayList
(kelas statis pribadi ArrayList<E> extends abstractList<E> mengimplementasikan RandomAccess, java.io.Serializable).
-
Memeriksa array untuk nilai tertentu.
Pengembang sering melakukan ini:
Set<String> set = new HashSet<String>(Arrays.asList(arr)); return set.contains(targetValue);
Kodenya berfungsi, tetapi tidak perlu mengubahnya
List
menjadiSet
. Mengonversi keSet
akan memerlukan waktu tambahan. Faktanya, semuanya sederhana:Arrays.asList(arr).contains(targetValue);
atau
for(String s: arr){ if(s.equals(targetValue)) return true; } return false;
Cara pertama jauh lebih singkat.
-
Menghapus elemen dari
List
dalam satu lingkaranPertimbangkan kode berikut yang menghapus elemen dalam satu lingkaran:
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); for (int i = 0; i < list.size(); i++) { list.remove(i); } System.out.println(list);
Kesimpulan:
[b, d]
Hal ini ternyata merupakan kesalahan yang serius. Ketika sebuah elemen dihapus, ukurannya
List
berkurang dan indeks elemen berubah.Jadi hindari metode ini jika Anda ingin menghapus beberapa elemen dalam satu lingkaran menggunakan indeks.
Anda mungkin tahu bahwa menggunakan iterator adalah solusi yang tepat untuk menghapus elemen dalam sebuah loop, dan Anda tahu bahwa loop gaya
for-each
berfungsi seperti iterator, tetapi ternyata tidak.Perhatikan kode berikut:
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); for (String s : list) { if (s.equals("a")) list.remove(s); }
Kami akan menerima ConcurrentModificationException .
Hal yang benar untuk dilakukan adalah:
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d")); Iterator<String> iter = list.iterator(); while (iter.hasNext()) { String s = iter.next(); if (s.equals("a")) { iter.remove(); } }
Metode ini
Dalam gaya loopnext()
harus dipanggil sebelumremove()
.for-each
, kompiler akan memanggil metode tersebutremove()
, dan hanya kemudiannext()
, yang akan memunculkan kesalahanConcurrentModificationException
. Anda dapat melihat kodenyaArrayList.iterator()
. -
Hashtable
melawanHashMap
.Karena implementasi yang sesuai, Hashtable adalah nama struktur datanya.
Namun di Java nama struktur datanya adalah
HashMap
. Salah satu perbedaan utama antaraHashtable
danHashMap
adalah bahwa iniHashtable
disinkronkan, jadi tidak boleh digunakanHashtable
di mana punHashMap
. -
Gunakan koleksi tanpa batasan konten
Di Java , koleksi tanpa batasan konten sering disalahartikan dengan koleksi dengan topeng tipe konten. Misalnya untuk set,
Set
ini adalah koleksi tanpa batasan konten, danSet<?>
- koleksi yang masih memiliki batasan, tetapi batasan tersebut sebenarnya tidak membatasi apa pun. Pertimbangkan kode berikut, yangList
digunakan tanpa batasan sebagai parameter metode:public static void add(List list, Object o){ list.add(o); } public static void main(String[] args){ List<String> list = new ArrayList<String>(); add(list, 10); String s = list.get(0); }
Kode ini akan memunculkan pengecualian:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at …
Menggunakan koleksi tanpa batasan konten sangat berbahaya karena Anda tidak dapat memastikan apa yang ada di dalamnya. Dan untuk memahami sepenuhnya perbedaan antara
Set
,Set<?>
danSet<Object>
- baca ini dan tautan ini . -
Tingkat akses
Sangat sering, pengembang menggunakan pengubah akses untuk bidang kelas
public
. Hal ini memudahkan untuk mendapatkan nilai bidang secara langsung. Lebih tepat menggunakan akses sebatas mungkin kepada anggota kelas. ArrayList
melawanLinkedList
Ketika pengembang tidak mengetahui perbedaannya
ArrayList
denganLinkedList
, mereka menggunakan yang pertama karena popularitasnya yang lebih besar. Namun, ada perbedaan besar dalam kinerja di antara keduanya. Faktanya, pilihan di antara elemen-elemen tersebut harus ditentukan oleh fitur internalnya -ArrayList
ini memungkinkan Anda mengakses elemen array arbitrer dengan cepat, danLinkedList
- dengan cepat menambah/menghapus elemen dalam array. Baca artikel di link ArrayList vs. LinkedList untuk memahami alasan perbedaan kinerjanya.Mutable
(Dapat Dimodifikasi) vs.Immutable
(Tidak Dapat Diubah)Objek yang tidak dapat diubah memiliki banyak keunggulan: kesederhanaan, keamanan, dll. Namun hal ini memerlukan objek terpisah untuk setiap nilai baru, dan memiliki terlalu banyak objek akan mengakibatkan kerugian performa. Harus ada keseimbangan ketika memilih antara objek yang bisa berubah dan objek yang tidak bisa diubah.
Pada dasarnya, untuk menghindari menyiapkan objek perantara, digunakan objek yang bisa diubah. Salah satu contoh klasiknya adalah penggabungan sejumlah besar string. Jika Anda menggunakan objek bertipe immutable
String
, maka Anda membuat banyak objek yang akan langsung masuk ke pengumpul sampah. Ini membuang-buang waktu dan energi CPU, jadi solusi yang tepat adalah dengan menggunakan objek yang bisa berubah (misalnyaStringBuilder
).String result=""; for(String s: arr){ result = result + s; }
Contoh lain penggunaan objek yang bisa diubah adalah meneruskan objek tersebut ke suatu metode. Ini akan memungkinkan Anda mengembalikan hasilnya dengan cara yang sama, tanpa membuat objek yang tidak perlu. Saat bekerja dengan objek besar, seperti koleksi, meneruskan koleksi ke metode pengurutan dan mengembalikan hasilnya ke koleksi lain adalah pemborosan sumber daya yang tidak perlu. ( Jawaban dari dasblinkenlight di Stack Overflow ).
-
Konstruktor kelas
Super
danSub
Kesalahan kompilasi ini disebabkan oleh fakta bahwa kelas leluhur tidak memiliki konstruktor default yang ditentukan. Di Java , kecuali Anda menentukan sendiri konstruktor kelas, kompiler akan membuat konstruktor default yang tidak memerlukan argumen. Jika konstruktor dideskripsikan di kelas
Super
sebagaiSuper(String s){}
, kompiler itu sendiri tidak akan menambahkan apa pun. Inilah yang kita lihat dalam contoh kita.Konstruktor kelas
Sub
, apa pun yang mana, akan memanggil konstruktor default kelasSuper
, karena tidak ada hal lain yang ditentukan. Karena tidak ada konstruktor default di kelasSuper
, ini akan menyebabkan kesalahan kompilasi.Solusi pertama untuk masalah ini adalah dengan menambahkan konstruktor default ke kelas
Super
public Super(){ System.out.println("Super"); }
Opsi kedua adalah menghapus konstruktor yang kami jelaskan dari kelas
Super
sehingga kompiler membuat konstruktor default.Dan opsi terakhir adalah menambahkan panggilan
super(value)
ke konstruktor kelasSub
sehingga konstruktor kelas yang ada dipanggil alih-alih konstruktor defaultSuper
-
" " atau konstruktor?
Ada dua cara untuk membuat string:
//1. использовать двойные кавычки String x = "abc";
//2. использовать конструктор String y = new String("abc");
Apa perbedaan di antara keduanya?
Anda dapat memahaminya dari contoh berikut:
String a = "abcd"; String b = "abcd"; System.out.println(a == b); // True System.out.println(a.equals(b)); // True String c = new String("abcd"); String d = new String("abcd"); System.out.println(c == d); // False System.out.println(c.equals(d)); // True
Untuk mempelajari lebih lanjut tentang bagaimana string disimpan dalam memori, baca Membuat String Java Menggunakan "" atau Konstruktor? .
GO TO FULL VERSION