java基礎教程欄目介紹集合類包含 Map 和 Collection 兩個大類
推薦(免費):java基礎教程
現(xiàn)在的一些高級編程語言都會提供各種開箱即用的數(shù)據(jù)結(jié)構(gòu)的實現(xiàn),像 Java 編程語言的集合框架中就提供了各種實現(xiàn),集合類包含 Map 和 Collection 兩個大類,其中 Collection 下面的 List 列表是我們經(jīng)常使用的集合類之一,很多的業(yè)務代碼都離不開它,今天就來看看 List 列表的一些坑。
第一個坑:Arrays.asList 方法返回的 List 不支持增加、刪除操作
例如我們執(zhí)行以下代碼:
List<String> strings = Arrays.asList("m", "g"); strings.add("h");
會拋出 java.lang.UnsupportedOperationException
異常,此時你內(nèi)心 OS what?明明返回的 ArrayList 為啥不能往里面增加元素,這以后還能好好的增加元素嗎?
,然后果斷開啟 Debug
大法:
發(fā)現(xiàn)返回的 ArrayList
并不是我們常用的 java.util.ArrayList
,而是 Arrays
的內(nèi)部類 java.util.Arrays.ArrayList
。進入方法 Arrays.asList
源碼如下:
public static <T> List<T> asList(T... a) { return new ArrayList<>(a); }
方法返回的是 Arrays
的靜態(tài)內(nèi)部類 java.util.Arrays.ArrayList
,該類雖然和 java.util.ArrayList
也繼承自抽象類 java.util.AbstractList
,但是通過該類的源碼發(fā)現(xiàn)它并沒有對抽象父類AbstractList
的 add
方法默認就是拋出 java.lang.UnsupportedOperationException
異常。
這個坑的根本原因是我們調(diào)用返回的 strings
的 add
方法是繼承自抽象父類的 add
方法,而抽象父類的方法默認就是拋出 java.lang.UnsupportedOperationException
這個異常。
第二個坑,Arrays.asList 方法返回的新 List 和該方法原始入?yún)?shù)組修改會相互影響
Arrays.asList
方法除了上面這個 不支持增加、刪除元素 這個坑之外,還有另外一個坑:
從以上代碼可以發(fā)現(xiàn),對原始數(shù)組的修改會影響我們通過 Arrays.asList
方法獲得的新 List
,深入 java.util.Arrays.ArrayList
的源碼:
private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable { private static final long serialVersionUID = -2764017481108945198L; private final E[] a; ArrayList(E[] array) { a = Objects.requireNonNull(array); } ... }
可以發(fā)現(xiàn)是直接使用了原始的數(shù)組,所有當我們使用 Arrays.asList
方式獲得的 List
時要特別注意,因為共享了數(shù)組,相互修改時可能產(chǎn)生一些意想不到的 Bug。標準的姿勢之一是將其作為 ArrayList
構(gòu)造方法的參數(shù)重新 new
一個 List
出來即可(e.g. List<String> stringList = new ArrayList<>(Arrays.asList(arrays))
)或者通過 Guava
庫中的 Lists.newArrayList
,將返回的新 List
和原始的數(shù)組解耦,就不會再互相影響了。
第三個坑,直接遍歷 List 集合刪除元素會報錯
在直接遍歷集合元素時增加、刪除元素會報錯,比如執(zhí)行如下代碼:
List<String> stringList = Lists.newArrayList("m", "g", "h"); for (String s : stringList) { if (Arrays.asList("m", "h").contains(s)) { stringList.remove(s); } }
以上代碼可以正常編譯通過,但是執(zhí)行時會拋出 java.util.ConcurrentModificationException
異常,查看其源碼可以發(fā)現(xiàn),刪除元素方法 remove
會使集合結(jié)構(gòu)發(fā)生修改,也就是 modCount(
集合實際修改的次數(shù))會修改,在循環(huán)過程中,會比較當前 List
的集合實際修改的次數(shù) modCount
與迭代器修改的次數(shù) expectedModCount
,而 expectedModCount
是初始化時的 modCount
, 二者不相等,就會報 ConcurrentModificationException
異常。解決方法主要有兩種方式,1.使用 ArrayList
的迭代器方式遍歷,然后調(diào)用其中的方法。2.在 JDK 1.8+ 可以使用 removeIf
方法進行刪除操作。
最后扎心一問:調(diào)用 ArrayList
的 remove
方法傳入 int
基本類型的數(shù)字和 Integer
包裝類型的數(shù)字,執(zhí)行結(jié)果是不是一樣的?
Atas ialah kandungan terperinci 記錄Java 集合類 List 的坑. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undress AI Tool
Gambar buka pakaian secara percuma

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Untuk mengendalikan transaksi JDBC dengan betul, anda mesti terlebih dahulu mematikan mod komit automatik, kemudian melakukan pelbagai operasi, dan akhirnya melakukan atau mengembalikan semula hasilnya; 1. Panggil Conn.SetAutOcommit (palsu) untuk memulakan transaksi; 2. Melaksanakan pelbagai operasi SQL, seperti memasukkan dan mengemaskini; 3. Panggil Conn.Commit () jika semua operasi berjaya, dan hubungi conn.rollback () jika pengecualian berlaku untuk memastikan konsistensi data; Pada masa yang sama, cuba-dengan-sumber harus digunakan untuk menguruskan sumber, mengendalikan pengecualian dengan betul dan menutup sambungan untuk mengelakkan kebocoran sambungan; Di samping itu, adalah disyorkan untuk menggunakan kolam sambungan dan menetapkan mata simpan untuk mencapai rollback separa, dan menyimpan urus niaga sesingkat mungkin untuk meningkatkan prestasi.

Gunakan kelas dalam pakej Java.Time untuk menggantikan kelas lama dan kelas kalendar; 2. Dapatkan tarikh dan masa semasa melalui LocalDate, LocalDateTime dan Tempatan Tempatan; 3. Buat tarikh dan masa tertentu menggunakan kaedah (); 4. Gunakan kaedah tambah/tolak untuk meningkatkan dan mengurangkan masa; 5. Gunakan zoneddatetime dan zonid untuk memproses zon waktu; 6. Format dan parse date string melalui DateTimeFormatter; 7. Gunakan segera untuk bersesuaian dengan jenis tarikh lama apabila perlu; pemprosesan tarikh di java moden harus memberi keutamaan untuk menggunakan java.timeapi, yang memberikan jelas, tidak berubah dan linear

Pra-formancetartuptimemoryusage, quarkusandmicronautleadduetocompile-timeprocessingandgraalvsupport, withquarkusoftenperforminglightbetterine serverless scenarios.tyvelopecosyste,

NetworkPortsandFireWallSworkTogethertoenableCommunicationWileensuringsecurity.1.networkportsarevirtualendpointsNumbered0-655 35, Withwell-KnownportsLike80 (http), 443 (https), 22 (ssh), dan25 (smtp) identitispecificservices.2.portsoperateovertcp (boleh dipercayai, c

Koleksi Sampah Java (GC) adalah mekanisme yang secara automatik menguruskan ingatan, yang mengurangkan risiko kebocoran ingatan dengan menuntut semula objek yang tidak dapat dicapai. 1.GC menghakimi kebolehcapaian objek dari objek akar (seperti pembolehubah stack, benang aktif, medan statik, dan lain -lain), dan objek yang tidak dapat dicapai ditandakan sebagai sampah. 2. Berdasarkan algoritma penandaan tanda, tandakan semua objek yang dapat dicapai dan objek yang tidak ditandai. 3. Mengamalkan strategi pengumpulan generasi: Generasi Baru (Eden, S0, S1) sering melaksanakan MinorGC; Orang tua melakukan kurang tetapi mengambil masa lebih lama untuk melakukan MajorGC; Metaspace Stores Metadata kelas. 4. JVM menyediakan pelbagai peranti GC: SerialGC sesuai untuk aplikasi kecil; ParallelGC meningkatkan throughput; CMS mengurangkan

Memilih jenis htmlinput yang betul dapat meningkatkan ketepatan data, meningkatkan pengalaman pengguna, dan meningkatkan kebolehgunaan. 1. Pilih jenis input yang sepadan mengikut jenis data, seperti teks, e -mel, tel, nombor dan tarikh, yang secara automatik boleh menyemak dan menyesuaikan diri dengan papan kekunci; 2. Gunakan HTML5 untuk menambah jenis baru seperti URL, Warna, Julat dan Carian, yang dapat memberikan kaedah interaksi yang lebih intuitif; 3. Gunakan pemegang tempat dan sifat -sifat yang diperlukan untuk meningkatkan kecekapan dan ketepatan pengisian bentuk, tetapi harus diperhatikan bahawa pemegang tempat tidak dapat menggantikan label.

GradleisthebetterChoiceFormostNewProjectSduetoitSsuperiorflexibility, Prestasi, danModernToolingSupport.1.Gradle'sGroovy/KOT lindslismoreconciseandexpressivethanmaven'sverbosexml.2.GradleOutPerformsMaveninBuildSpeedWithIncrementalcompilation, BuildCac

Defer digunakan untuk melaksanakan operasi tertentu sebelum fungsi pulangan, seperti sumber pembersihan; Parameter dinilai dengan serta-merta apabila menangguhkan, dan fungsi-fungsi dilaksanakan mengikut urutan terakhir (LIFO); 1. Pelbagai penahanan dilaksanakan dalam urutan terbalik pengisytiharan; 2. Biasanya digunakan untuk pembersihan yang selamat seperti penutupan fail; 3. Nilai pulangan yang dinamakan boleh diubah suai; 4. Ia akan dilaksanakan walaupun panik berlaku, sesuai untuk pemulihan; 5. Elakkan penyalahgunaan menangguhkan gelung untuk mengelakkan kebocoran sumber; Penggunaan yang betul boleh meningkatkan keselamatan kod dan kebolehbacaan.
