Heim >Java >javaLernprogramm >Zusammenfassung der Fragen und Antworten zum Java Collections-Interview

Zusammenfassung der Fragen und Antworten zum Java Collections-Interview

怪我咯
怪我咯Original
2017-04-05 16:05:521561Durchsuche

1. Was ist das Java Collection Framework? Nennen Sie einige Vorteile des Sammlungs-Frameworks?

Es gibt Sammlungen in jeder Programmiersprache, und die erste Version von Java enthielt mehrere Sammlungsklassen: Vector, Stack, HashTable und Array. Mit der weit verbreiteten Verwendung von Sammlungen schlug Java 1.2 ein Sammlungsframework vor, das alle Sammlungsschnittstellen, Implementierungen und Algorithmen umfasst. Java durchläuft seit langem den Prozess der Verwendung von Generika und gleichzeitigen Sammlungsklassen bei gleichzeitiger Gewährleistung der Thread-Sicherheit. Es umfasst auch blockierende Schnittstellen und ihre Implementierungen im Java-Parallelitätspaket. Einige der Vorteile des Collection-Frameworks sind folgende:

(1) Reduzieren Sie die Entwicklungskosten, indem Sie Kern-Collection-Klassen verwenden, anstatt unsere eigenen Collection-Klassen zu implementieren.

(2) Die Codequalität wird durch die Verwendung streng getesteter Collection-Framework-Klassen verbessert.

(3) Durch die Verwendung der im JDK enthaltenen Sammlungsklassen können die Kosten für die Codepflege gesenkt werden.

(4) Wiederverwendbarkeit und Bedienbarkeit.

2. Welche Vorteile haben Generika im Sammelrahmen?

Mit Java 1.5 wurden Generika eingeführt, und alle Sammlungsschnittstellen und Implementierungen nutzen sie in großem Umfang. Mithilfe von Generika können wir einer Sammlung einen Object-Typ bereitstellen, den sie enthalten kann. Wenn Sie also Elemente anderer Typen hinzufügen, wird die Kompilierung als Fehler angezeigt. Dies vermeidet ClassCastException zur Laufzeit, da Sie zur Kompilierungszeit eine Fehlermeldung erhalten. Generics machen den Code außerdem sauberer, wir müssen keine expliziten Konvertierungen und den Operator „instanceOf“ verwenden. Es bringt auch Vorteile für die Laufzeit, da keine typgeprüften Bytecode-Anweisungen generiert werden.

3. Was sind die grundlegenden Schnittstellen des Java Collection Frameworks?

Sammlung ist die Stammschnittstelle der Sammlungshierarchie. Eine Sammlung stellt eine Menge von Objekten dar, die ihre Elemente sind. Die Java-Plattform bietet keine direkte Implementierung dieser Schnittstelle.

Set ist ein Set, das keine doppelten Elemente enthalten darf. Diese Schnittstelle modelliert eine mathematische Mengenabstraktion und wird zur Darstellung von Mengen wie einem Kartenspiel verwendet.

Liste ist eine geordnete Sammlung, die wiederholte Elemente enthalten kann. Sie können auf jedes Element über seinen Index zugreifen. Die Liste ähnelt eher einem Array, dessen Länge sich dynamisch ändert.

Map ist ein Objekt, das Schlüssel zu Werten zuordnet. Eine Map kann keine doppelten Schlüssel enthalten: Jeder Schlüssel kann höchstens einen Wert zuordnen.

Einige andere Schnittstellen sind Queue, Dequeue, SortedSet, SortedMap und ListIterator.

4. Warum erbt Collection nicht von klonbaren und serialisierbaren Schnittstellen?

Die Sammlungsschnittstelle gibt eine Reihe von Objekten an, und die Objekte sind ihre Elemente. Wie diese Elemente verwaltet werden, wird durch die spezifische Implementierung der Sammlung bestimmt. Beispielsweise erlauben einige Collection-Implementierungen wie List doppelte Elemente, während andere wie Set dies nicht tun. Viele Collection-Implementierungen verfügen über eine öffentliche Klonmethode. Es macht jedoch keinen Sinn, es in alle Implementierungen von Sammlungen einzufügen. Dies liegt daran, dass Collection eine abstrakte Darstellung ist. Was zählt, ist die Umsetzung.

Die Semantik und Implikationen des Klonens oder der Serialisierung spielen eine Rolle, wenn es um spezifische Implementierungen geht. Daher sollte die Implementierung entscheiden, wie es geklont oder serialisiert wird oder ob es überhaupt geklont oder serialisiert werden kann.

Ermöglichen Sie Klonen und Serialisierung in allen Implementierungen, was letztendlich zu weniger Flexibilität und mehr Einschränkungen führt. Die spezifische Implementierung sollte entscheiden, ob sie geklont und serialisiert werden kann.

5. Warum erbt die Map-Schnittstelle nicht die Collection-Schnittstelle?

Obwohl die Map-Schnittstelle und ihre Implementierung ebenfalls Teil des Sammlungsframeworks sind, ist Map keine Sammlung und Sammlungen sind keine Karten. Daher macht es keinen Sinn, dass Map Collection erbt und umgekehrt.

Wenn Map die Collection-Schnittstelle erbt, wohin gehen die Elemente? Map enthält Schlüssel-Wert-Paare, die Methoden zum Extrahieren von Schlüssel- oder Wertelistensammlungen bereitstellen, entspricht jedoch nicht der Spezifikation „Satz von Objekten“.

6.Was ist Iterator?

Iterator-Schnittstelle bietet eine Schnittstelle zum Durchlaufen jeder Sammlung. Wir können die Iterator-Methode verwenden, um eine Iterator-Instanz aus einer Sammlung abzurufen. Iteratoren ersetzen die Aufzählung im Java-Collection-Framework. Iteratoren ermöglichen es dem Aufrufer, Elemente während des Iterationsprozesses zu entfernen.

7. Was ist der Unterschied zwischen Enumeration- und Iterator-Schnittstellen?

Aufzählung ist doppelt so schnell wie Iterator und benötigt weniger Speicher. Die Aufzählung ist sehr einfach und erfüllt grundlegende Bedürfnisse. Im Vergleich zur Enumeration ist Iterator jedoch sicherer, da es verhindert, dass andere Threads die Sammlung ändern, während eine Sammlung durchlaufen wird.

Iterator ersetzt Enumeration im Java Collections Framework. Iteratoren ermöglichen es dem Aufrufer, Elemente aus einer Sammlung zu entfernen, während dies bei Enumerationen nicht möglich ist. Die Namen der Iterator-Methoden wurden verbessert, um ihre Funktionalität klarer zu machen.

8. Warum gibt es keine Methode wie Iterator.add(), um Elemente zu einer Sammlung hinzuzufügen?

Die Semantik ist unklar. Es ist bekannt, dass das Iterator-Protokoll die Reihenfolge der Iteration nicht garantiert. Beachten Sie jedoch, dass ListIterator keine Additionsoperation bereitstellt, die die Reihenfolge der Iteration sicherstellt.

9. Warum verfügt der Iterator nicht über eine Methode, die das nächste Element direkt abrufen kann, ohne den Cursor zu bewegen?

Es kann auf der obersten Ebene des aktuellen Iterators implementiert werden, wird jedoch selten verwendet. Wenn es der Schnittstelle hinzugefügt wird, muss es bei jeder Vererbung implementiert werden, was keinen Sinn ergibt.

10. Was ist der Unterschied zwischen Iterator und ListIterator?

(1) Wir können Iterator zum Durchlaufen von Set- und List-Sammlungen verwenden, während ListIterator nur List durchqueren kann.

(2) Iterator kann nur vorwärts durchlaufen, während LIstIterator in beide Richtungen durchlaufen kann.

(3) ListIterator erbt von der Iterator-Schnittstelle und fügt dann einige zusätzliche Funktionen hinzu, z. B. das Hinzufügen eines Elements, das Ersetzen eines Elements und das Abrufen der Indexposition des vorherigen oder folgenden Elements.

11. Welche verschiedenen Möglichkeiten gibt es, eine Liste zu durchlaufen?

List<String> strList = new ArrayList<>();
//使用for-each循环
for(String obj : strList){
     System.out.println(obj);
}
//using iterator
Iterator<String> it = strList.iterator();
while(it.hasNext()){
     String obj = it.next();
     System.out.println(obj);
}

Die Verwendung von Iteratoren ist threadsicherer, da dadurch sichergestellt wird, dass bei Änderung des aktuell durchlaufenen Sammlungselements eine ConcurrentModificationException ausgelöst wird.

12. Was verstehen Sie unter dem Iterator-Fail-Fast-Attribut?

Jedes Mal, wenn wir versuchen, das nächste Element abzurufen, prüft die Iterator-Fail-Fast-Eigenschaft, ob Änderungen in der aktuellen Sammlungsstruktur vorliegen. Wenn eine Änderung gefunden wird, wird eine ConcurrentModificationException ausgelöst. Alle Iterator-Implementierungen in Collection sind auf Ausfallsicherheit ausgelegt (mit Ausnahme gleichzeitiger Collection-Klassen wie ConcurrentHashMap und CopyOnWriteArrayList).

13.Was ist der Unterschied zwischen Fail-Fast und Fail-Safe?

Die Fail-Fast-Eigenschaft von Iterator funktioniert mit der aktuellen Sammlung, sodass sie von Änderungen in der Sammlung nicht beeinflusst wird. Alle Sammlungsklassen im Java.util-Paket sind auf Ausfallsicherheit ausgelegt, während die Sammlungsklassen in java.util.concurrent ausfallsicher sind. Ausfallsichere Iteratoren lösen eine ConcurrentModificationException aus, während ausfallsichere Iteratoren niemals eine ConcurrentModificationException auslösen.

14. Wie vermeide ich ConcurrentModificationException beim Iterieren einer Sammlung?

Beim Durchlaufen einer Sammlung können wir gleichzeitige Sammlungsklassen verwenden, um ConcurrentModificationException zu vermeiden, z. B. die Verwendung von CopyOnWriteArrayList anstelle von ArrayList.

15. Warum gibt es keine spezifische Implementierung der Iterator-Schnittstelle?

Die Iterator-Schnittstelle definiert Methoden zum Durchlaufen von Sammlungen, ihre Implementierung liegt jedoch in der Verantwortung der Sammlungsimplementierungsklasse. Jede Sammlungsklasse, die einen Iterator zum Durchlaufen zurückgibt, verfügt über eine eigene innere Iterator-Implementierungsklasse.

Auf diese Weise können Sammlungsklassen auswählen, ob der Iterator ausfallsicher oder ausfallsicher ist. Beispielsweise ist der ArrayList-Iterator ausfallsicher und der CopyOnWriteArrayList-Iterator ist ausfallsicher.

16.Was ist UnsupportedOperationException?

UnsupportedOperationException ist eine Ausnahme, die angibt, dass ein Vorgang nicht unterstützt wird. Es wird häufig in JDK-Klassen verwendet. Im Sammlungsframework löst java.util.Collections.UnmodifiableCollection diese Ausnahme bei allen Add- und Remove-Vorgängen aus.

17. Wie funktioniert HashMap in Java?

HashMap speichert Schlüssel-Wert-Paare in der Map.Entrystatischeninternen Klassenimplementierung. HashMap verwendet einen Hash-Algorithmus und in den Put- und Get-Methoden die Methoden hashCode() und equal(). Wenn wir die Put-Methode aufrufen, indem wir das Schlüssel-Wert-Paar übergeben, verwendet HashMap Key hashCode() und den Hashing-Algorithmus, um den Index zu finden, in dem das Schlüssel-Wert-Paar gespeichert ist. Der Eintrag wird in einer LinkedList gespeichert. Wenn der Eintrag vorhanden ist, wird mit der Methode equal() überprüft, ob der übergebene Schlüssel bereits vorhanden ist. Wenn er vorhanden ist, wird der Wert überschrieben. Wenn er nicht vorhanden ist, wird ein neuer Eintrag erstellt speichert es dann. Wenn wir die get-Methode durch Übergabe des Schlüssels aufrufen, verwendet sie erneut hashCode(), um den Index im Array zu finden, und verwendet dann die Methode equal(), um den richtigen Eintrag herauszufinden, und gibt dann seinen Wert zurück. Die folgenden Bilder erläutern die Details.

Weitere wichtige Themen in Bezug auf HashMap sind Kapazität, Auslastungsfaktor und Schwellenwertanpassung. Die standardmäßige Anfangskapazität von HashMap beträgt 32 und der Auslastungsfaktor beträgt 0,75. Der Schwellenwert ist der Auslastungsfaktor multipliziert mit der Kapazität. Wenn die Kartengröße größer als der Schwellenwert ist, wird HashMap den Karteninhalt erneut aufbereiten und die größere Kapazität verwenden. Die Kapazität ist immer eine Potenz von 2. Wenn Sie also wissen, dass Sie eine große Anzahl von Schlüssel-Wert-Paaren speichern müssen, z. B. zum Zwischenspeichern von Daten aus einer Datenbank, ist es eine gute Idee, die HashMap mit zu initialisieren die richtigen Kapazitäts- und Auslastungsfaktorpraktiken.

18. Welche Bedeutung haben die Methoden hashCode() und equal()?

HashMap verwendet die Methoden hashCode() und equal() des Key-Objekts, um den Index des Schlüssel-Wert-Paares zu bestimmen. Diese Methoden werden auch verwendet, wenn wir versuchen, Werte von HashMap abzurufen. Wenn diese Methoden nicht korrekt implementiert sind (in diesem Fall erzeugen zwei verschiedene Schlüssel möglicherweise dieselben hashCode()- und equal()-Ausgaben), betrachtet die HashMap sie als gleich und überschreibt sie, anstatt sie an verschiedenen Stellen zu speichern. Ebenso verwenden alle Sammlungsklassen, die die Speicherung doppelter Daten nicht zulassen, hashCode() und equal(), um Duplikate zu finden. Daher ist es sehr wichtig, sie korrekt zu implementieren. Die Implementierung von equal() und hashCode() sollte den folgenden Regeln folgen:

(1) Wenn o1.equals(o2), dann ist o1.hashCode() == o2.hashCode() immer wahr.

(2)如果o1.hashCode() == o2.hashCode(),并不意味着o1.equals(o2)会为true。

19.我们能否使用任何类作为Map的key?

我们可以使用任何类作为Map的key,然而在使用它们之前,需要考虑以下几点:

(1)如果类重写了equals()方法,它也应该重写hashCode()方法。

(2)类的所有实例需要遵循与equals()和hashCode()相关的规则。请参考之前提到的这些规则。

(3)如果一个类没有使用equals(),你不应该在hashCode()中使用它。

(4)用户自定义key类的最佳实践是使之为不可变的,这样,hashCode()值可以被缓存起来,拥有更好的性能。不可变的类也可以确保hashCode()和equals()在未来不会改变,这样就会解决与可变相关的问题了。

比如,我有一个类MyKey,在HashMap中使用它。

//传递给MyKey的name参数被用于equals()和hashCode()中
MyKey key = new MyKey(&#39;Pankaj&#39;); //assume hashCode=1234
myHashMap.put(key, &#39;Value&#39;);
// 以下的代码会改变key的hashCode()和equals()值
key.setName(&#39;Amit&#39;); //assume new hashCode=7890
//下面会返回null,因为HashMap会尝试查找存储同样索引的key,而key已被改变了,匹配失败,返回null
myHashMap.get(new MyKey(&#39;Pankaj&#39;));

那就是为何String和Integer被作为HashMap的key大量使用。

20.Map接口提供了哪些不同的集合视图?

Map接口提供三个集合视图:

(1)Set keyset():返回map中包含的所有key的一个Set视图。集合是受map支持的,map的变化会在集合中反映出来,反之亦然。当一个迭代器正在遍历一个集合时,若map被修改了(除迭代器自身的移除操作以外),迭代器的结果会变为未定义。集合支持通过Iterator的Remove、Set.remove、removeAll、retainAll和clear操作进行元素移除,从map中移除对应的映射。它不支持add和addAll操作。

(2)Collection values():返回一个map中包含的所有value的一个Collection视图。这个collection受map支持的,map的变化会在collection中反映出来,反之亦然。当一个迭代器正在遍历一个collection时,若map被修改了(除迭代器自身的移除操作以外),迭代器的结果会变为未定义。集合支持通过Iterator的Remove、Set.remove、removeAll、retainAll和clear操作进行元素移除,从map中移除对应的映射。它不支持add和addAll操作。

(3)Set44bf986331d5d9c3931140ad55669b0c> entrySet():返回一个map钟包含的所有映射的一个集合视图。这个集合受map支持的,map的变化会在collection中反映出来,反之亦然。当一个迭代器正在遍历一个集合时,若map被修改了(除迭代器自身的移除操作,以及对迭代器返回的entry进行setValue外),迭代器的结果会变为未定义。集合支持通过Iterator的Remove、Set.remove、removeAll、retainAll和clear操作进行元素移除,从map中移除对应的映射。它不支持add和addAll操作。

21.HashMap和HashTable有何不同?

(1)HashMap允许key和value为null,而HashTable不允许。

(2)HashTable是同步的,而HashMap不是。所以HashMap适合单线程环境,HashTable适合多线程环境。

(3)在Java1.4中引入了LinkedHashMap,HashMap的一个子类,假如你想要遍历顺序,你很容易从HashMap转向LinkedHashMap,但是HashTable不是这样的,它的顺序是不可预知的。

(4)HashMap提供对key的Set进行遍历,因此它是fail-fast的,但HashTable提供对key的Enumeration进行遍历,它不支持fail-fast。

(5)HashTable被认为是个遗留的类,如果你寻求在迭代的时候修改Map,你应该使用CocurrentHashMap。

22.如何决定选用HashMap还是TreeMap?

对于在Map中插入、删除和定位元素这类操作,HashMap是最好的选择。然而,假如你需要对一个有序的key集合进行遍历,TreeMap是更好的选择。基于你的collection的大小,也许向HashMap中添加元素会更快,将map换为TreeMap进行有序key的遍历。

23.ArrayList和Vector有何异同点?

ArrayList和Vector在很多时候都很类似。

(1)两者都是基于索引的,内部由一个数组支持。

(2)两者维护插入的顺序,我们可以根据插入顺序来获取元素。

(3)ArrayList和Vector的迭代器实现都是fail-fast的。

(4)ArrayList和Vector两者允许null值,也可以使用索引值对元素进行随机访问。

以下是ArrayList和Vector的不同点。

(1)Vector是同步的,而ArrayList不是。然而,如果你寻求在迭代的时候对列表进行改变,你应该使用CopyOnWriteArrayList。

(2)ArrayList比Vector快,它因为有同步,不会过载。

(3)ArrayList更加通用,因为我们可以使用Collections工具类轻易地获取同步列表和只读列表。

24.Array和ArrayList有何区别?什么时候更适合用Array?

Array可以容纳基本类型和对象,而ArrayList只能容纳对象。

Array是指定大小的,而ArrayList大小是固定的。

Array bietet nicht so viele Funktionen wie ArrayList, wie z. B. addAll, removeAll und iterator. Obwohl ArrayList eindeutig die bessere Wahl ist, gibt es Zeiten, in denen Array besser ist.

(1) Wenn die Größe der Liste angegeben wurde, erfolgt die meiste Zeit zum Speichern und Durchlaufen.

(2) Beim Durchlaufen grundlegender -Datentypen kann die Arbeit an Listen mit Basistypen einer bestimmten Größe langsam sein, obwohl Sammlungen Autoboxing verwenden, um die Codierungsaufgabe zu erleichtern.

(3) Wenn Sie ein mehrdimensionales Array verwenden möchten, ist es einfacher, [][] als List658a6c8c8956eca63df9b922e1300853> zu verwenden.

25. Was ist der Unterschied zwischen ArrayList und LinkedList?

Sowohl ArrayList als auch LinkedList implementieren die List-Schnittstelle, es gibt jedoch einige Unterschiede zwischen ihnen.

(1) ArrayList ist eine Datenstruktur, die auf einem von Array unterstützten Index basiert und daher einen wahlfreien Zugriff auf Elemente mit einer Komplexität von O(1) ermöglicht. LinkedList speichert jedoch jeweils eine Reihe von Knotendaten Jeder Knoten ist mit dem vorherigen und nächsten Knoten verbunden. Obwohl es eine Methode zum Abrufen von Elementen mithilfe von Indizes gibt, besteht die interne Implementierung darin, vom Startpunkt aus zum indizierten Knoten zu durchlaufen und dann das Element zurückzugeben. Die Zeitkomplexität beträgt O (n), was langsamer als ArrayList ist.

(2) Im Vergleich zu ArrayList ist das Einfügen, Hinzufügen und Löschen eines Elements in LinkedList schneller, da beim Einfügen eines Elements in die Mitte weder die Größe des Arrays geändert noch der Index aktualisiert werden muss . .

(3) LinkedList verbraucht mehr Speicher als ArrayList, da jeder Knoten in LinkedList Verweise auf den vorherigen und nächsten Knoten speichert.

26. Welche Sammlungsklassen bieten wahlfreien Zugriff auf Elemente?

Die Klassen ArrayList, HashMap, TreeMap und HashTable bieten wahlfreien Zugriff auf Elemente.

27.Was ist EnumSet?

java.util.EnumSet ist eine Sammlungsimplementierung, die Aufzählungstypen verwendet. Wenn eine Sammlung erstellt wird, müssen alle Elemente in der Aufzählungssammlung explizit oder implizit von einem einzigen angegebenen Aufzählungstyp stammen. EnumSet ist nicht synchronisiert und lässt keine Nullelemente zu. Es bietet auch einige nützliche Methoden, wie zum Beispiel copyOf(Collection c), of(E first,E...rest) und complementOf(EnumSet s).

28. Welche Sammlungsklassen sind threadsicher?

Vector, HashTable, Properties und Stack sind Synchronisationsklassen, daher sind sie threadsicher und können in einer Multithread-Umgebung verwendet werden. Die Parallelitäts-API von Java 1.5 umfasst einige Sammlungsklassen, die Änderungen während der Iteration ermöglichen. Da sie alle auf Klonen der Sammlung arbeiten, sind sie in einer Multithread-Umgebung sicher.

29. Was ist die gleichzeitige Sammlungsklasse?

Das Java 1.5 Concurrent-Paket (java.util.concurrent) enthält threadsichere Sammlungsklassen, die es ermöglichen, Sammlungen während der Iteration zu ändern. Iteratoren sind auf Ausfallsicherheit ausgelegt und lösen eine ConcurrentModificationException aus. Einige Klassen sind: CopyOnWriteArrayList, ConcurrentHashMap, CopyOnWriteArraySet.

30.Was ist BlockingQueue?

Java.util.concurrent.BlockingQueue ist eine Warteschlange. Beim Abrufen oder Entfernen eines Elements wird darauf gewartet, dass die Warteschlange nicht leer wird. Beim Hinzufügen eines Elements wird darauf gewartet, dass die Warteschlange leer wird -leer. Verfügbarer Platz. Die BlockingQueue-Schnittstelle ist Teil des Java-Collection-Frameworks und wird hauptsächlich zur Implementierung des Producer-Consumer-Musters verwendet. Wir müssen uns nicht darum kümmern, darauf zu warten, dass der Produzent über verfügbaren Speicherplatz oder der Verbraucher über verfügbare Objekte verfügt, da alles in der BlockingQueue-Implementierungsklasse verwaltet wird. Java bietet zentralisierte BlockingQueue-Implementierungen wie ArrayBlockingQueue, LinkedBlockingQueue, PriorityBlockingQueue, SynchronousQueue usw.

31. Was sind Warteschlangen und Stapel und listen ihre Unterschiede auf?

Sowohl Stapel als auch Warteschlangen werden zum Vorspeichern von Daten verwendet. java.util.Queue ist eine Schnittstelle und ihre Implementierungsklasse befindet sich im Java-Parallelitätspaket. Mithilfe von Warteschlangen können Elemente nach dem FIFO-Prinzip (First-In-First-Out) abgerufen werden. Dies ist jedoch nicht immer der Fall. Die Deque-Schnittstelle ermöglicht das Abrufen von Elementen von beiden Enden.

Ein Stapel ähnelt einer Warteschlange, ermöglicht jedoch den Last-in-First-out (LIFO)-Abruf von Elementen.

Stack ist eine Klasse, die von Vector erweitert wird, und Queue ist eine Schnittstelle.

32.Was ist die Collections-Klasse?

Java.util.Collections ist eine Dienstprogrammklasse, die nur statische Methoden enthält, die Sammlungen bearbeiten oder zurückgeben. Es enthält polymorphe Algorithmen, die Sammlungen bearbeiten, eine neue Sammlung zurückgeben, die von der angegebenen Sammlung unterstützt wird, und einige andere Dinge. Diese Klasse enthält Methoden für Sammlungsframework-Algorithmen, wie z. B. binäre Suche, Sortierung, Mischen und umgekehrte Reihenfolge.

33.Was sind die Comparable- und Comparator-Schnittstellen?

Wenn wir die Sortiermethode Array oder Collection verwenden möchten, müssen wir die von Java bereitgestellte Comparable-Schnittstelle in einer benutzerdefinierten Klasse implementieren. Die Comparable-Schnittstelle verfügt über die Methode CompareTo(T OBJ), die von der Sortiermethode verwendet wird. Wir sollten diese Methode überschreiben, sodass sie eine negative Ganzzahl, 0, oder eine positive Ganzzahl zurückgibt, wenn das „diese“-Objekt kleiner, gleich oder größer als das übergebene Objektargument ist. In den meisten praktischen Fällen möchten wir jedoch nach verschiedenen Parametern sortieren. Als CEO möchte ich beispielsweise Mitarbeiter nach Gehalt sortieren, und eine Personalabteilung möchte sie nach Alter sortieren. Dies ist die Situation, in der wir die Comparator-Schnittstelle verwenden müssen, da die Methodenimplementierung Comparable.compareTo(Object o) nur basierend auf einem Feld sortieren kann und wir das Feld nicht entsprechend den Anforderungen der Objektsortierung auswählen können. Die Implementierung der Methode „compare(Object o1, Object o2)“ der Comparator-Schnittstelle muss zwei Objektparameter übergeben. Wenn der erste Parameter kleiner als der zweite ist, wird eine negative Ganzzahl zurückgegeben. 0 wird zurückgegeben; wenn der erste Parameter kleiner als der zweite Parameter ist, wird eine negative Ganzzahl zurückgegeben. Wenn eins größer als der zweite ist, wird eine positive Ganzzahl zurückgegeben.

34. Was ist der Unterschied zwischen Comparable- und Comparator-Schnittstellen?

Comparable- und Comparator-Schnittstellen werden zum Sortieren von Objektsammlungen oder Arrays verwendet. Die Comparable-Schnittstelle wird verwendet, um eine natürliche Reihenfolge von Objekten bereitzustellen, und wir können sie verwenden, um eine Reihenfolge basierend auf einer einzigen Logik bereitzustellen.

Die Comparator-Schnittstelle wird verwendet, um verschiedene Sortieralgorithmen bereitzustellen. Wir können den Comparator auswählen, den wir zum Sortieren einer bestimmten Objektsammlung verwenden müssen.

35. Wie sortieren wir eine Reihe von Objekten?

Wenn wir ein Array von Objekten sortieren müssen, können wir die Methode Arrays.sort() verwenden. Wenn wir eine Liste von Objekten sortieren müssen, können wir die Methode Collection.sort() verwenden. Beide Klassen verfügen über eine überladene Methode sort() für natürliche Sortierung (mit Comparable) oder kriterienbasierte Sortierung (mit Comparator). Collections verwendet intern die Methode Array-Sortierung, sodass beide die gleiche Leistung haben, mit der Ausnahme, dass Collections Zeit braucht, um die Liste in ein Array zu konvertieren.

36. Wenn eine Sammlung als Parameter an eine Funktion übergeben wird, wie können wir sicherstellen, dass die Funktion sie nicht ändern kann?

Wir können die Methode Collections.unmodifiableCollection(Collection c) verwenden, um eine schreibgeschützte Sammlung zu erstellen, bevor wir sie als Parameter übergeben. Dadurch wird sichergestellt, dass jede Operation, die die Sammlung ändert, eine UnsupportedOperationException auslöst.

37. Wie erstellen wir eine synchronisierte Sammlung aus einer bestimmten Sammlung?

Wir können Collections.synchronizedCollection(Collection c) verwenden, um eine synchronisierte (threadsichere) Sammlung basierend auf der angegebenen Sammlung zu erhalten.

38. Welche allgemeinen Algorithmen sind im Sammlungsframework implementiert?

Das Java-Collection-Framework bietet gängige Algorithmusimplementierungen wie Sortieren und Suchen. Die Collections-Klasse enthält Implementierungen dieser Methoden. Die meisten Algorithmen arbeiten mit Listen, einige sind jedoch für alle Arten von Sammlungen verfügbar. Einige Algorithmen umfassen Sortieren, Suchen, Mischen und Max-Min.

39. Was ist das große O? Nennen Sie einige Beispiele?

Ein großes O beschreibt die Leistung eines Algorithmus in Bezug auf eine Reihe von Elementen in der Datenstruktur. Die Collection-Klasse ist die eigentliche Datenstruktur, und wir wählen normalerweise eine Collection-Implementierung basierend auf Zeit, Speicher und Leistung mit einem großen O. Beispiel: Beispiel 1: get(index i) von ArrayList ist eine konstante Zeitoperation, die nicht von der Anzahl der Elemente in der Liste abhängt. Seine Leistung ist also O(1). Beispiel 2: Die Leistung einer linearen Suche in einem Array oder einer Liste beträgt O(n), da wir alle Elemente durchlaufen müssen, um das erforderliche Element zu finden.

40. Was sind die Best Practices im Zusammenhang mit dem Java Collections Framework?

(1) Wählen Sie den richtigen Sammeltyp entsprechend Ihren Anforderungen. Wenn beispielsweise die Größe angegeben ist, verwenden wir Array anstelle von ArrayList. Wenn wir eine Karte basierend auf der Einfügereihenfolge durchqueren möchten, müssen wir eine TreeMap verwenden. Wenn wir keine Wiederholung wünschen, sollten wir Set verwenden.

(2) Einige Sammlungsklassen ermöglichen die Angabe der Anfangskapazität. Wenn wir also die Anzahl der gespeicherten Elemente schätzen können, können wir diese verwenden und ein erneutes Aufbereiten oder Ändern der Größe vermeiden.

(3) Basierend auf der Schnittstellenprogrammierung statt auf der Implementierung basierender Programmierung, ermöglicht es uns, die Implementierung später einfach zu ändern.

(4) Verwenden Sie immer typsichere Generika, um ClassCastException zur Laufzeit zu vermeiden.

(5) Verwenden Sie die vom JDK bereitgestellte unveränderliche Klasse als Schlüssel der Karte, um zu vermeiden, dass Sie hashCode() und equal() selbst implementieren.

(6) Verwenden Sie die Toolklasse „Collections“ so oft wie möglich oder erhalten Sie eine schreibgeschützte, synchronisierte oder leere Sammlung, anstatt Ihre eigene Implementierung zu schreiben. Es ermöglicht die Wiederverwendbarkeit des Codes und bietet eine bessere Stabilität und Wartbarkeit.


Das obige ist der detaillierte Inhalt vonZusammenfassung der Fragen und Antworten zum Java Collections-Interview. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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