Inhaltsverzeichnis
Der erste Fallstrick: Die von der Arrays.asList-Methode zurückgegebene Liste unterstützt keine Hinzufügungs- und Löschvorgänge
第二个坑,Arrays.asList 方法返回的新 List 和该方法原始入参数组修改会相互影响
第三个坑,直接遍历 List 集合删除元素会报错
Heim Java JavaBase Notieren Sie die Fallstricke der Java-Sammlungsklassenliste

Notieren Sie die Fallstricke der Java-Sammlungsklassenliste

Dec 17, 2020 pm 05:16 PM
java list

Java Basic TutorialIn der Spalte wird die Sammlungsklasse vorgestellt, die zwei Hauptkategorien umfasst: Karte und Sammlung

Notieren Sie die Fallstricke der Java-Sammlungsklassenliste

Empfohlen (kostenlos): Java Basic Tutorial

Einige fortgeschrittene Programmiersprachen ​​​​​bietet jetzt verschiedene Implementierungen einer vorgefertigten Datenstruktur, wie z. B. das Sammlungsframework der Programmiersprache Java, mit verschiedenen Implementierungen. Die Sammlungsklasse umfasst zwei Hauptkategorien: Karte und Sammlung Sammlung ist die Sammlungsklasse, die wir häufig verwenden. Erstens sind viele Geschäftscodes untrennbar damit verbunden. Werfen wir heute einen Blick auf einige Fallstricke von List.

Der erste Fallstrick: Die von der Arrays.asList-Methode zurückgegebene Liste unterstützt keine Hinzufügungs- und Löschvorgänge

Wenn wir beispielsweise den folgenden Code ausführen:

List<String> strings = Arrays.asList("m", "g");
strings.add("h");

wird eine java.lang.UnsupportedOperationException</ ausgelöst Code> Ausnahme. Was geht Ihnen zu diesem Zeitpunkt am Herzen? Warum können der zurückgegebenen ArrayList keine Elemente hinzugefügt werden? Können Elemente in Zukunft ordnungsgemäß hinzugefügt werden? und dann Debug entscheidend aktivieren Dafa: java.lang.UnsupportedOperationException 异常,此时你内心 OS what?明明返回的 ArrayList 为啥不能往里面增加元素,这以后还能好好的增加元素吗?,然后果断开启 Debug 大法:

Notieren Sie die Fallstricke der Java-Sammlungsklassenliste

发现返回的 ArrayList 并不是我们常用的 java.util.ArrayList,而是 Arrays 的内部类 java.util.Arrays.ArrayList。进入方法 Arrays.asList 源码如下:

public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

方法返回的是 Arrays 的静态内部类 java.util.Arrays.ArrayList,该类虽然和 java.util.ArrayList 也继承自抽象类 java.util.AbstractList ,但是通过该类的源码发现它并没有对抽象父类AbstractListadd 方法默认就是抛出 java.lang.UnsupportedOperationException 异常。

Notieren Sie die Fallstricke der Java-Sammlungsklassenliste

这个坑的根本原因是我们调用返回的 stringsadd 方法是继承自抽象父类的 add 方法,而抽象父类的方法默认就是抛出 java.lang.UnsupportedOperationException 这个异常。

第二个坑,Arrays.asList 方法返回的新 List 和该方法原始入参数组修改会相互影响

Arrays.asList 方法除了上面这个 不支持增加、删除元素 这个坑之外,还有另外一个坑:

Notieren Sie die Fallstricke der Java-Sammlungsklassenliste

从以上代码可以发现,对原始数组的修改会影响我们通过 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);
        }
        
        ...
        
     }

可以发现是直接使用了原始的数组,所有当我们使用 Arrays.asList 方式获得的 List 时要特别注意,因为共享了数组,相互修改时可能产生一些意想不到的 Bug。标准的姿势之一是将其作为 ArrayList 构造方法的参数重新 new 一个 List 出来即可(e.g. List<String> stringList = new ArrayList<>(Arrays.asList(arrays)))或者通过 Guava 库中的 Lists.newArrayList ,将返回的新 List 和原始的数组解耦,就不会再互相影响了。

第三个坑,直接遍历 List 集合删除元素会报错

在直接遍历集合元素时增加、删除元素会报错,比如执行如下代码:

List<String> stringList = Lists.newArrayList("m", "g", "h");
for (String s : stringList) {
    if (Arrays.asList("m", "h").contains(s)) {
        stringList.remove(s);
    }
}

以上代码可以正常编译通过,但是执行时会抛出 java.util.ConcurrentModificationException 异常,查看其源码可以发现,删除元素方法 remove 会使集合结构发生修改,也就是 modCount(集合实际修改的次数)会修改,在循环过程中,会比较当前 List 的集合实际修改的次数 modCount 与迭代器修改的次数 expectedModCount ,而 expectedModCount 是初始化时的 modCount, 二者不相等,就会报 ConcurrentModificationException 异常。解决方法主要有两种方式,1.使用 ArrayList 的迭代器方式遍历,然后调用其中的方法。2.在 JDK 1.8+ 可以使用 removeIf 方法进行删除操作。

最后扎心一问:调用 ArrayListremove 方法传入 int 基本类型的数字和 Integer

Notieren Sie die Fallstricke der Java-Sammlungsklassenliste🎜🎜 Es wurde festgestellt, dass die zurückgegebene ArrayList nicht unsere häufig verwendete java.util.ArrayList ist, sondern Interne Klasse java.util.Arrays.ArrayList von Arrays. Geben Sie die Methode Arrays.asList ein. Der Quellcode lautet wie folgt: Die Methode 🎜rrreee🎜 gibt die statische interne Klasse java.util.Arrays.ArrayList von Arrays zurück . Obwohl die Klasse und java.util.ArrayList auch von der abstrakten Klasse java.util.AbstractList erben, wird sie über den Quellcode dieser Klasse gefunden dass es keinen Verweis auf die abstrakte übergeordnete Klasse AbstractList hat. Die Methode add löst standardmäßig die Ausnahme java.lang.UnsupportedOperationException aus. 🎜🎜Notieren Sie die Fallstricke der Java-Sammlungsklassenliste. 🎜🎜Das Die Hauptursache für die Falle besteht darin, dass die add-Methode der von unserem Aufruf zurückgegebenen strings von der add-Methode der abstrakten übergeordneten Klasse geerbt wird und die Methode der abstrakten übergeordneten Klasse. Standardmäßig wird die Ausnahme java.lang.UnsupportedOperationException ausgelöst. 🎜🎜Die zweite Gefahr besteht darin, dass sich die neue Liste, die von der Arrays.asList-Methode zurückgegeben wird, und die Änderung der ursprünglichen Parametergruppe der Methode gegenseitig beeinflussen 🎜🎜Arrays.asList-Methode, mit Ausnahme der oben genannten 🎜Tat Das Hinzufügen oder Löschen von Elementen wird nicht unterstützt🎜 Neben dieser Grube gibt es noch eine weitere Grube: 🎜🎜Notieren Sie die Fallstricke der Java-Sammlungsklassenliste🎜🎜Aus dem obigen Code können wir erkennen, dass Änderungen am ursprünglichen Array Auswirkungen auf die neue Liste haben, die wir über die Arrays erhalten. asList-Methode. Gehen Sie tiefer: 🎜rrreee🎜Es kann festgestellt werden, dass das ursprüngliche Array direkt verwendet wird, also wenn wir den Arrays.asList-Methode zum Abrufen der Liste Bitte seien Sie besonders vorsichtig, wenn Sie sich gegenseitig ändern, da Arrays gemeinsam genutzt werden und beim gegenseitigen Ändern einige unerwartete Fehler auftreten können. Eine der Standardaktionen besteht darin, es als Parameter des ArrayList-Konstruktors zu verwenden, um eine Liste zu neu (z. B. List<string stringlist="new" arraylist>(Arrays.asList(arrays))</string>) oder über Lists.newArrayList in der Guava-Bibliothek wird der neue verwendet Der zurückgegebene Code>Liste ist vom ursprünglichen Array entkoppelt und beeinflusst sich nicht mehr gegenseitig. 🎜🎜Die dritte Gefahr besteht darin, dass beim direkten Durchlaufen der Auflistungselemente ein Fehler gemeldet wird. 🎜🎜Beim Hinzufügen oder Löschen von Elementen während der direkten Durchquerung der Auflistungselemente wird beispielsweise ein Fehler gemeldet Der folgende Code: 🎜rrreee🎜Der obige Code kann normal kompiliert werden, aber wenn er ausgeführt wird, tritt eine java.util.ConcurrentModificationException-Ausnahme auf Die Elementmethode remove ändert die Sammlungsstruktur, d. h. modCount( Die tatsächliche Anzahl der Änderungen an der Sammlung) wird während der Schleife geändert zur aktuellen List-Sammlung modCount wird mit der Anzahl der Änderungen am Iterator expectedModCount verglichen, und expectedModCount ist der modCount während der Initialisierung. Wenn die beiden nicht gleich sind, wird eine ConcurrentModificationException-Ausnahme gemeldet. Es gibt zwei Hauptlösungen: 1. Verwenden Sie zum Durchlaufen die Iteratormethode von ArrayList und rufen Sie dann die darin enthaltenen Methoden auf. 2. In JDK 1.8+ können Sie die Methode removeIf verwenden, um Löschvorgänge durchzuführen. 🎜🎜Abschließend noch eine herzzerreißende Frage: Rufen Sie die Methode remove von ArrayList auf und übergeben Sie die Basistypnummer int und Integer Sind die Ausführungsergebnisse der Verpackungstypnummern gleich? 🎜

Das obige ist der detaillierte Inhalt vonNotieren Sie die Fallstricke der Java-Sammlungsklassenliste. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

PHP-Tutorial
1512
276
Python Argparse erforderte Argument -Beispiel Python Argparse erforderte Argument -Beispiel Aug 11, 2025 pm 09:42 PM

Bei der Verwendung des ArgParse -Moduls können die bereitgestellten Parameter erreicht werden, indem erforderlich ist. 1. Verwenden Sie erforderliche = treu, um optionale Parameter (z. B. -Eingabe) zu setzen, um erforderlich zu sein. Wenn dies bei der Ausführung des Skripts nicht bereitgestellt wird, wird ein Fehler gemeldet. 2. Positionsparameter sind standardmäßig erforderlich, und es ist nicht erforderlich, erforderlich zu sein, die erforderliche = true; 3.. Es wird empfohlen, Positionsparameter für die erforderlichen Parameter zu verwenden. Gelegentlich werden die optionalen Parameter von erforderlich = true verwendet, um die Flexibilität aufrechtzuerhalten. 4. Erforderlich = True ist der direkteste Weg, um Parameter zu steuern. Nach der Verwendung muss der Benutzer beim Aufrufen des Skripts entsprechende Parameter bereitstellen, da das Programm ansonsten einen Fehler auffordert und beendet.

Was sind Kommentare in Java? Was sind Kommentare in Java? Aug 12, 2025 am 08:20 AM

KommentarinjavareignedByTheCompilerandusedForExplanation, Notizen, ordisablingcode.therearethreetypes: 1) Single-Linde-Deals startwith // und Lastuntiltheendoftheline; 2) Multi-Linde-Bingin-Dokumentation und-undcantranmultipline; 3) Dokumentation

Die besten IDES für Java -Entwicklung: eine vergleichende Überprüfung Die besten IDES für Java -Entwicklung: eine vergleichende Überprüfung Aug 12, 2025 pm 02:55 PM

Thebestjavaidein2024Dependyourneeds: 1.CHOOSEINTELLIJIDEAFORPROFESSIONAL, ENTERPRISE, Orull-StackDevelopmentDuetoitsSuperiorCodeIntelligence, Frameworkintegration, andtooling.2. Useclipseforhoxhensibilsibsibilität, LegacyPro-Eigenschaften, oderweigte, oderweigende, oderweilen, oderweilen, orwhenopenen-seourzatioten, legacyprojekts, orwhenopenen-seourzatioten, legacyprojekts, orwhenopenen-seourcatiatiox

So verwenden Sie die HTTPClient -API in Java So verwenden Sie die HTTPClient -API in Java Aug 12, 2025 pm 02:27 PM

Der Kern der Verwendung des Javahttpclientapi besteht darin, einen Httpclient zu erstellen, einen httprequest zu erstellen und httPesponse zu verarbeiten. 1. Verwenden Sie httpclient.newhttpclient () oder httpclient.newbuilder (), um Zeitüberschreitungen, Proxy usw. zu konfigurieren, um Clients zu erstellen. 2. Verwenden Sie httprequest.newbuilder (), um URI, Methode, Kopfzeile und Körper zu setzen, um Anfragen zu erstellen. 3.. Senden Sie synchrone Anfragen über Client.send () oder asynchrone Anfragen über Client.sendasync (); 4. Verwenden Sie Bodyhandlers.Ofstr

Fix: Ethernet 'Nicht identifiziertes Netzwerk' Fix: Ethernet 'Nicht identifiziertes Netzwerk' Aug 12, 2025 pm 01:53 PM

RestartyourRouterandComputertoresolvetemporaryglitches.2.RunthenetworkrouBleshooterviathesystemTraytoAutomaticFixCommonissues.3.RewhewIpadDressusesusesusesusesuSuseingCommandpromptasadMinistratorByRunningipconfig/Release, Ipconfig/Reufreset und Netshwinset und Netschon/Rufe, Netshwinset und Netshwinset und NETSHNE und NETSETH und NETSETH und NETHN

Wie man Saiten in Java vergleicht Wie man Saiten in Java vergleicht Aug 12, 2025 am 10:00 AM

Verwenden Sie .Equals (), um den String -Inhalt zu vergleichen, da == nur Objektreferenzen und nicht tatsächliche Zeichen vergleichen; 2. Verwenden Sie .EqualSignoreCase () beim Vergleich des Ignorierens; 3.. Verwenden Sie .Compareto () bei alphabetisch sortierender und comparetoignorecase (), wenn Sie den Fall ignorieren; 4. Vermeiden Sie es, Strings anzurufen, die möglicherweise null sein können. Equals () sollte verwendet werden, um "buchstäblich" .Eequals (Variable) oder Objekte zu verwenden. Ausgleiche (STR1, STR2), um Nullwerte sicher zu verarbeiten; Kurz gesagt, achten Sie immer eher auf den Vergleich des Inhalts als auf Referenz,

Was ist eine Linkedlist in Java? Was ist eine Linkedlist in Java? Aug 12, 2025 pm 12:14 PM

LinkedList ist eine bidirektionale verknüpfte Liste in Java, die Liste und Deque -Schnittstellen implementiert. Es ist für Szenarien geeignet, in denen häufig Elemente eingefügt und gelöscht werden. Insbesondere beim Betrieb an beiden Enden der Liste hat es eine hohe Effizienz, aber die Zufallszugriffsleistung ist schlecht und die Zeitkomplexität ist O (N). Einfügen und Löschen können O (1) an bekannten Stellen erreichen. Daher ist es geeignet, Stapel, Warteschlangen oder Situationen zu implementieren, in denen Strukturen dynamisch modifiziert werden müssen, und eignet sich nicht für readintensive Operationen, die häufig nach Index zugreifen. Die endgültige Schlussfolgerung ist, dass die LinkedList besser als ArrayList ist, wenn sie häufig geändert wird, aber weniger Zugriffe hat.

Excel finden und ersetzen Sie nicht funktionieren Excel finden und ersetzen Sie nicht funktionieren Aug 13, 2025 pm 04:49 PM

CheckSearchsets -ähnliche "MatchentirecellContents" und "Matchcase" ByexpandingOptionssinfindandReplace, sorgen für "Lookin" IssettoValuesand "Innere" toCorrectScope;

See all articles