Heim > Java > javaLernprogramm > Hauptteil

Interviewfragen zur Java-Sammlung, die große Unternehmen am liebsten stellen

伊谢尔伦
Freigeben: 2016-11-26 13:14:31
Original
1346 Leute haben es durchsucht

Nachdem ich einige JAVA-Interviewfragen von sogenannten großen Unternehmen gelesen hatte, stellte ich fest, dass sie alle großen Wert auf die Verwendung von JAVA-Sammlungsklassen legen, aber ich weiß wirklich sehr wenig über diesen Aspekt, also sollte ich mir die Zeit nehmen, es zu lernen Es.

Das java.util-Paket enthält eine Reihe wichtiger Sammlungsklassen. Bei Sammlungsklassen müssen Sie vor allem die interne Struktur und den Iterationsmodus zum Durchlaufen der Sammlung beherrschen.

Schnittstelle: Sammlung

Sammlung ist die grundlegendste Sammlungsschnittstelle. Eine Sammlung repräsentiert eine Gruppe von Objekten, also die Elemente der Sammlung. Einige Sammlungen erlauben identische Elemente, andere nicht. Manche sortieren, andere nicht. Das Java SDK stellt keine Klassen bereit, die direkt von Collection erben. Die vom Java SDK bereitgestellten Klassen sind alle „Unterschnittstellen“, die von Collection erben, wie z. B. List und Set.

Alle Klassen, die die Collection-Schnittstelle implementieren, müssen zwei Standardkonstruktoren bereitstellen: Der parameterlose Konstruktor wird zum Erstellen einer leeren Collection verwendet, und der Konstruktor mit einem Collection-Parameter wird zum Erstellen einer neuen Collection verwendet dieselben Elemente wie die übergebene Sammlung. Der letztere Konstruktor ermöglicht dem Benutzer das Kopieren einer Sammlung.

Die Hauptschnittstellenmethode: boolean add(Ojbect c)
Obwohl sie einen booleschen Wert zurückgibt, zeigt sie nicht an, ob die Addition erfolgreich ist oder nicht. Die Bedeutung dieses Rückgabewerts ist, dass nach add() ist ausgeführt, die Sammlung Ob sich der Inhalt geändert hat (dh ob sich die Anzahl, Position usw. der Elemente geändert haben). Ähnliche AddAll, Remove, RemoveAll, RemainAll sind gleich.

Verwenden Sie den Iterator-Modus, um eine Sammlung zu durchlaufen.

Eine Sammlung verfügt über eine wichtige Methode: iterator(), die einen Iterator (Iterator) zum Durchlaufen aller Elemente der Sammlung zurückgibt. Das Iterator-Muster kann die Zugriffslogik aus verschiedenen Sammlungsklassen abstrahieren und so vermeiden, dass die interne Struktur der Sammlung dem Client offengelegt wird. Die typische Verwendung ist wie folgt:

Iterator it = collection.iterator(); // 获得一个迭代器
while(it.hasNext()) {
    Object obj = it.next(); // 得到下一个元素
}
Nach dem Login kopieren

Es ist nicht erforderlich, den „Zeiger“ zum Durchlaufen der Sammlung beizubehalten. Alle internen Zustände werden vom Iterator verwaltet und dieser Iterator wird von generiert die Sammlungsklasse über die Factory-Methode.

Der spezifische Typ des von jeder Sammlungsklasse zurückgegebenen Iterators kann unterschiedlich sein, aber alle implementieren die Iterator-Schnittstelle. Daher müssen wir uns nicht darum kümmern, um welche Art von Iterator es sich handelt Iterator-Schnittstelle. Dies ist der Vorteil von Schnittstellen und der Leistungsfähigkeit von Objektorientierung.

Um sicherzustellen, dass der Durchlaufvorgang reibungslos abgeschlossen wird, muss sichergestellt werden, dass der Inhalt der Sammlung während des Durchlaufvorgangs nicht geändert wird (mit Ausnahme der Methode „remove()“ von Iterator). Um eine zuverlässige Durchquerung sicherzustellen, gilt Folgendes: Verwenden Sie diese Sammlung nur in einem Thread oder synchronisieren Sie den Durchquerungscode über mehrere Threads hinweg.

Die beiden von der Collection-Schnittstelle abgeleiteten Schnittstellen sind List und Set.

Listenschnittstelle

Liste ist eine geordnete Sammlung. Mit dieser Schnittstelle können Sie die Einfügeposition jedes Elements genau steuern. Benutzer können über den Index (die Position des Elements in der Liste, ähnlich einem Array-Index), der dem Java-Array ähnelt, auf Elemente in der Liste zugreifen. Im Gegensatz zum unten erwähnten Set erlaubt List die gleichen Elemente.

Zusätzlich zu der für die Collection-Schnittstelle erforderlichen iterator()-Methode bietet List auch eine listIterator()-Methode, die eine ListIterator-Schnittstelle zurückgibt. Im Vergleich zur Standard-Iterator-Schnittstelle verfügt ListIterator über mehr add() und die Ähnliche Methoden ermöglichen das Hinzufügen, Löschen, Festlegen von Elementen und das Vorwärts- oder Rückwärtslaufen.

Gemeinsame Klassen, die die List-Schnittstelle implementieren, sind LinkedList, ArrayList, Vector und Stack.

LinkedList-Klasse

LinkedList implementiert die List-Schnittstelle und lässt Nullelemente zu. Darüber hinaus stellt LinkedList zusätzliche Get-, Remove- und Insert-Methoden am Anfang oder Ende von LinkedList bereit. Diese Operationen ermöglichen die Verwendung von LinkedList als Stack, Warteschlange oder Deque.

Beachten Sie, dass LinkedList keine synchronisierten Methoden hat. Wenn mehrere Threads gleichzeitig auf eine Liste zugreifen, müssen sie die Zugriffssynchronisierung selbst implementieren. Eine Lösung besteht darin, beim Erstellen der Liste eine synchronisierte Liste zu erstellen:
List list = Collections.synchronizedList(new LinkedList(…));

ArrayList-Klasse

ArrayList implementiert ein Array variabler Größe. Es erlaubt alle Elemente, einschließlich null. ArrayList ist nicht synchronisiert.
Die Methoden „size“, „isEmpty“, „get“ und „set“ werden in konstanter Zeit ausgeführt. Allerdings sind die Kosten der Add-Methode eine amortisierte Konstante, und das Addieren von n Elementen erfordert O(n) Zeit. Andere Methoden haben eine lineare Laufzeit.

Jede ArrayList-Instanz verfügt über eine Kapazität (Capacity), die der Größe des Arrays entspricht, das zum Speichern von Elementen verwendet wird. Diese Kapazität erhöht sich automatisch, wenn neue Elemente hinzugefügt werden, der Wachstumsalgorithmus ist jedoch nicht definiert. Wenn eine große Anzahl von Elementen eingefügt werden muss, kann die Methode „sichsureCapacity“ aufgerufen werden, um die Kapazität der ArrayList vor dem Einfügen zu erhöhen und so die Einfügeeffizienz zu verbessern.

Wie LinkedList ist auch ArrayList nicht synchronisiert.

Vector-Klasse

Vector ist ArrayList sehr ähnlich, aber Vector ist synchronisiert. Obwohl der von Vector erstellte Iterator dieselbe Schnittstelle hat wie der von ArrayList erstellte Iterator, da Vector synchronisiert ist, ändert ein anderer Thread den Status des Vectors, wenn ein Iterator erstellt und verwendet wird (z. B. indem ein Element hinzugefügt oder entfernt wird). , ConcurrentModificationException wird beim Aufruf der Iterator-Methode ausgelöst, daher muss die Ausnahme abgefangen werden.

Stack-Klasse

Stack erbt von Vector und implementiert einen Last-In-First-Out-Stack. Stack bietet 5 zusätzliche Methoden, mit denen Vector als Stack verwendet werden kann. Die grundlegenden Push- und Pop-Methoden sowie die Peek-Methode holen sich das Element oben im Stapel, die leere Methode testet, ob der Stapel leer ist, und die Suchmethode erkennt die Position eines Elements im Stapel. Der Stapel ist nach seiner Erstellung ein leerer Stapel.

Set-Schnittstelle

Set ist eine Sammlung, die keine wiederholten Elemente enthält, d. h. zwei beliebige Elemente e1 und e2 haben e1.equals(e2)=false und Set hat höchstens eines Nullelement.

Offensichtlich unterliegt der Set-Konstruktor der Einschränkung, dass der übergebene Collection-Parameter keine doppelten Elemente enthalten darf.

Bitte beachten Sie: Veränderliche Objekte müssen mit Vorsicht behandelt werden. Wenn ein veränderliches Element in einem Set seinen Zustand ändert und Object.equals(Object)=true verursacht, führt dies zu einigen Problemen.

Map-Schnittstelle

Bitte beachten Sie, dass Map nicht die Collection-Schnittstelle erbt, die den Schlüssel zur Wertzuordnung bereitstellt. Eine Map kann nicht denselben Schlüssel enthalten und jeder Schlüssel kann nur einen Wert zuordnen. Die Map-Schnittstelle bietet drei Arten von Satzansichten. Der Inhalt der Karte kann als Satz von Schlüsselsätzen, als Satz von Wertsätzen oder als Satz von Schlüsselwertzuordnungen betrachtet werden.

Hashtable-Klasse

Hashtable erbt die Map-Schnittstelle und implementiert eine Hash-Tabelle der Schlüsselwertzuordnung. Als Schlüssel oder Wert kann jedes Nicht-Null-Objekt verwendet werden.

Um Daten hinzuzufügen, verwenden Sie put(key, value) und um Daten zu entfernen, verwenden Sie get(key). Der Zeitaufwand dieser beiden Grundoperationen ist konstant.

Hashtable passt die Leistung über zwei Parameter an: Anfangskapazität und Auslastungsfaktor. Normalerweise erreicht der Standardlastfaktor 0,75 ein besseres Gleichgewicht zwischen Zeit und Raum. Durch Erhöhen des Auslastungsfaktors kann Platz gespart werden, die entsprechende Suchzeit erhöht sich jedoch, was sich auf Vorgänge wie „Abrufen“ und „Put“ auswirkt.

Ein einfaches Beispiel für die Verwendung von Hashtable ist wie folgt: Geben Sie 1, 2 und 3 in die Hashtable ein, und ihre Schlüssel sind „eins“, „zwei“ bzw. „drei“:
Hashtable-Nummern = new Hashtable( );
numbers.put(“one”, new Integer(1));
numbers.put(“two”, new Integer(2));
numbers.put(“ three“, new Integer(3));

Um eine Zahl wie 2 abzurufen, verwenden Sie den entsprechenden Schlüssel:
Integer n = (Integer)numbers.get(“two”);
System.out. println(“two = ” + n);

Da das als Schlüssel verwendete Objekt die Position des entsprechenden Werts durch Berechnung seiner Hash-Funktion bestimmt, muss jedes als Schlüssel verwendete Objekt die Methoden hashCode und equal implementieren. Die Methoden hashCode und equal erben von der Stammklasse Object. Wenn Sie eine benutzerdefinierte Klasse als Schlüssel verwenden, seien Sie gemäß der Definition der Hash-Funktion sehr vorsichtig, wenn die beiden Objekte gleich sind, d. h. obj1.equals( obj2)=true, dann muss ihr HashCode gleich sein, aber wenn zwei Objekte unterschiedlich sind, ist ihr HashCode nicht unbedingt unterschiedlich. Wenn der HashCode zweier verschiedener Objekte gleich ist, wird dieses Phänomen als Konflikt bezeichnet Der Zeitaufwand für den Betrieb der Hash-Tabelle erhöht sich. Versuchen Sie daher, eine genau definierte hashCode()-Methode zu definieren, um die Hash-Tabellenoperationen zu beschleunigen.

Wenn dasselbe Objekt einen anderen Hash-Code hat, führt die Operation der Hash-Tabelle zu unerwarteten Ergebnissen (die erwartete Get-Methode gibt null zurück. Um dieses Problem zu vermeiden, müssen Sie sich nur eines merken: gleichzeitig kopieren). Die Zeit entspricht der Methode und der HashCode-Methode, anstatt nur eine davon zu schreiben.

Hashtable ist synchron.

HashMap-Klasse

HashMap ähnelt Hashtable, außer dass HashMap asynchron ist und Null zulässt, d. h. Nullwert und Nullschlüssel. , aber wenn HashMap als Sammlung behandelt wird (die Methode „values()“ kann eine Sammlung zurückgeben), ist der Zeitaufwand für die Iteratoroperation proportional zur Kapazität der HashMap. Wenn die Leistung iterativer Operationen sehr wichtig ist, sollten Sie daher die Anfangskapazität von HashMap nicht zu hoch oder den Auslastungsfaktor zu niedrig einstellen.

WeakHashMap-Klasse

WeakHashMap ist eine verbesserte HashMap, die „schwache Referenzen“ auf Schlüssel implementiert. Wenn ein Schlüssel nicht mehr extern referenziert wird, kann der Schlüssel von GC recycelt werden.

Zusammenfassung

Wenn Vorgänge wie Stapel und Warteschlangen beteiligt sind, sollten Sie die Verwendung von List in Betracht ziehen. Wenn Sie einen schnellen Direktzugriff auf Elemente benötigen, sollten Sie LinkedList verwenden , sollten Sie ArrayList verwenden.

Wenn sich das Programm in einer Single-Thread-Umgebung befindet oder der Zugriff nur in einem Thread erfolgt, sollten Sie asynchrone Klassen in Betracht ziehen, die effizienter sind. Wenn mehrere Threads gleichzeitig eine Klasse betreiben können, sollten synchronisierte Klassen dies tun verwendet werden.

Achten Sie besonders auf die Funktionsweise der Hash-Tabelle. Das als Schlüssel verwendete Objekt muss die Methoden equal und hashCode korrekt überschreiben.

Versuchen Sie, die Schnittstelle und nicht den tatsächlichen Typ zurückzugeben, z. B. List anstelle von ArrayList, damit sich der Clientcode nicht ändern muss, wenn Sie ArrayList in Zukunft durch LinkedList ersetzen müssen. Das ist Programmierung zur Abstraktion.



Verwandte Etiketten:
Quelle:php.cn
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!