JDK1.8.0_144 Adresse de téléchargement: //www.vevb.com/softs/551512.html
AbstractMap Abstract Class implémente quelques méthodes simples et générales, ce qui n'est pas difficile en soi. Mais il existe deux méthodes dans cette classe abstraite qui valent la peine d'être prêts attention. La mise en œuvre du code source de la méthode de la clé et des valeurs peut être considérée comme des modèles de style manuel.
Les classes abstraites sont généralement implémentées sous forme de squelette pour implémenter des méthodes courantes pour leurs sous-classes respectives. Dans l'article précédent, nous avons expliqué l'interface MAP, et cet article analyse et étudie la classe abstraite abstraite.
Il existe de nombreuses structures de données de type map en Java. AbstractMap, comme leur implémentation squelette, met en œuvre certaines méthodes de l'interface MAP, c'est-à-dire qu'elle fournit des méthodes publiques pour ses sous-classes, et diverses cartes sans implémentation peuvent être différentes.
Une classe abstraite ne peut pas créer directement des instances de classes abstraites via le nouveau mot clé, mais il peut avoir des constructeurs. AbstractMap fournit un constructeur sans paramètre modifié protégé, ce qui signifie que seule sa sous-classe peut accéder (bien sûr, c'est une classe abstraite elle-même, et d'autres classes ne peuvent pas être instanciées directement), c'est-à-dire que seule sa sous-classe peut appeler ce constructeur sans paramètre.
Une interface d'entrée est définie en interne dans l'interface MAP. Cette interface est une implémentation interne de la carte MAP pour maintenir une paire de valeurs de clé de valeur clé, et la valeur clé est stockée dans cette carte. AbstractMap implémente cette interface interne, il y en a deux au total: l'une est le simple mental mutable et l'autre est le simple immuable-immutable.
classe statique publique SimpleEntry <k, v> implémente l'entrée <k, v>, java.io.serializable
L'interface map.entry <k, v> est implémentée et sérialisable (peut être sérialisée).
Sa méthode est relativement simple, qui sont toutes des opérations de prise de valeurs et de stockage des valeurs. La définition de la valeur clé est une modification finale, ce qui signifie qu'il s'agit d'une référence immuable. De plus, sa méthode SetValue est légèrement spéciale. La valeur stockée n'est pas la valeur stockée, mais l'ancienne valeur renvoyée. Ce que vous devez apprendre, ce sont les méthodes égales et HashCode qu'il réécrit.
Le booléen public est égal (objet o) {if (! (o instanceof map.entry)) // Pour déterminer si les paramètres sont de type map.Entry, si les égaux sont égaux, la première chose à faire est d'être le même type return false; Map.entry <? ,?> e = (map.entry <? ,?>) o; // Forcer le type d'objet à map.Entry Type, le paramètre utilise "?" Au lieu de "k, v" car le type de générique sera effacé au moment de l'exécution. Le compilateur ne sait pas ce qu'est le type K et V, return eq (key, e.getKey ()) && eq (value, e.getValue ()); // la clé et la valeur appellent respectivement la méthode EQ pour le jugement, et les égaux sont égaux lorsque les deux renvoient. } Eq booléen statique privé (objet O1, objet O2) {return o1 == null? O2 == NULL: O1.Equals (O2); // Cet opérateur à trois éléments est également très simple, mais il convient de noter que bien que O1 et O2 soient des types d'objets ici, la méthode équivalente du type d'objet est référencée par "==", donc ne pensez pas qu'il y a un problème ici, car en réalité, le type O1 peut être la méthode égal. }Pour réécrire correctement la méthode égaux et être utilisé correctement, vous devez généralement réécrire la méthode HashCode.
public int hashcode () {return (key == null? 0: key.hashcode ()) ^ (value == null? 0: value.hashcode ()); // Lorsque les valeurs de la clé et de la valeur ne sont pas nuls, le HashCode sera xored. }Classe statique publique SimpleimutableEntry <k, v> implémente l'entrée <k, v>, java.io.Serializable Simple-ImmutableEntry
L'entrée définie comme immuable est en fait immuable car elle ne fournit pas la méthode SetValue, et ne peut naturellement pas être modifiée via la méthode SetValue lorsque plusieurs threads sont accessibles simultanément. Par rapport à SimpleEntry, ses variables de clé et de valeur sont définies comme des types finaux. L'appel de la méthode SetValue lancera une exception non soutenue d'Exception.
Ses méthodes égales et HashCode sont cohérentes avec SimpleEntry.
Ensuite, vérifiez quelles méthodes de l'interface MAP sont implémentées par la classe AbstractMap Abstract.
public int size ()
Une méthode d'entrée est définie dans la carte, qui renvoie la collection d'ensemble de map.entry. La méthode de taille de la collection de set est appelée directement, qui est la taille de la carte.
public booléen iSempty ()
Appelez la méthode de taille ci-dessus, égale à 0, elle est vide.
Booléen public contienty (clé d'objet)
L'implémentation de cette méthode est relativement simple. En appelant la méthode d'entrée, itérateur de la collection de sets est obtenu et traversé avec la touche de paramètre. La carte peut être stockée en tant que valeur clé de NULL. Étant donné que Key = NULL est stocké en carte avec un stockage spécial spécial (la valeur de code de hash ne peut pas être calculée), nous avons également fait un moyen de déterminer si la clé de paramètre est vide.
Boolean public contient une valeur (valeur de l'objet)
Cette implémentation de la méthode est cohérente avec CONTAINSKEY.
public v get (clé d'objet)
Cette implémentation de la méthode est similaire aux deux ci-dessus, la différence est que ce qui précède est égal à la booléenne, et cette méthode renvoie la valeur.
public v put (ke key, v valeur)
La méthode de stockage des paires de valeurs clés dans la carte n'est pas implémentée en détail, et une conception non soutenue de l'Opération sera directement lancée.
public V Supprimer (clé d'objet)
Supprimez la paire de valeurs de clé de clé de clé spécifiée dans la carte via la touche de paramètre. Cette méthode est également très simple. Il traverse également la collection d'ensembles de Map.Entry via un itérateur, trouve la valeur de clé correspondante et supprime Map.Entry en appelant la méthode ITERATOR # supprimer.
public void putall (map <? étend k ,? étend v> m)
Cette méthode est également très simple pour parcourir la carte entrante et simplement appeler la méthode de put pour l'enregistrer.
public void clear ()
Appelez la méthode d'entrée pour obtenir la collection SET, puis appelez la méthode SET # Clear () pour l'effacer.
Set public <k> keyset ()
Renvoie la collection d'ensemble des valeurs de clé de carte. AbstractMap définit une variable de membre "Set transitoire <K> Keyset". Dans JDK7, la variable de la clé est modifiée par volatile, mais dans JDK8, il n'est pas modifié par volatile. Il est expliqué dans les commentaires sur la variable de la clé que la méthode pour accéder à ces champs n'est pas synchronisée par elle-même, et volatile ne peut garantir la sécurité des filetages. L'implémentation de la méthode de la clé est intéressante.
Tout d'abord, pensez à cette méthode pour renvoyer l'ensemble des valeurs clés. Naturellement, nous pouvons penser à une méthode de mise en œuvre simple, traverser le tableau d'entrée et éliminer la valeur clé et le mettre dans l'ensemble des ensembles, similaire au code suivant:
public set <K> keySet () {set <K> ks = null; pour (map.entry <k, v> entrée: entryset ()) {ks.add (entry.getKey ()); } return ks;}Cela signifie que chaque fois que la méthode de la clé est appelée, elle traversera le réseau d'entrée et l'efficacité sera considérablement réduite lorsque le volume de données est important. Je dois dire que le code source JDK est très bien écrit et qu'il n'adopte pas la méthode de traversée. Si vous ne parcourez pas l'entrée, comment savez-vous que cette carte a ajouté une paire de valeurs clés à valeur clé pour le moment?
La réponse est de réimplémenter une nouvelle collection de jeux personnalisés dans la méthode de la clé, et la méthode Iterator est réécrite dans cette collection de jeux personnalisés. Voici la clé. La méthode Iterator renvoie l'interface Iterator, et ici il est réimplémenté. En appelant la méthode d'entrée, puis en appelant sa méthode Iterator. Ce qui suit est analysé en combinaison avec le code:
public set <K> keySet () {set <K> ks = keyset; // Set transitoire défini <K> KeySet if (ks == null) {// Le premier appel est définitivement nul, créez un exemple défini via le code suivant ks = new AbstractSet <k> () {// Créer un ensemble personnalisé Iterator <K> Iterator () {// Rewrite the iteract Iterator <entrée <k, v >> i = entryset (). Iterator (); // Créer un ensemble de collection Iterator iterator public booléan hasnext () {return i.hasnext (); // Le jugement de la valeur clé est le jugement de l'entrée} public k next () {return i.next (). GetKey (); // La valeur de clé suivante consiste à prendre l'entrée # getKey} public void retire () {i.Remove (); // Supprimer la valeur de clé, supprimer l'entrée}}; } public int size () {// Le jeu réécrit # la méthode de taille renvoie abstractmap.this.size (); // La valeur de la clé est la taille de toute la carte, alors appelez simplement la méthode de taille de cette classe. Ceci est une classe interne. Utilisez ce mot-clé pour représenter directement cette classe. Il devrait indiquer que la méthode de taille dans AbstractMap est appelée. Sans cela, cela signifie qu'il s'agit d'une méthode statique statique} public boolean isEmpty () {// Le jeu réécrit # iSempty méthode renvoie abstractmap.this.isempty (); // Pour savoir s'il y a une valeur clé, cela signifie si la carte est vide, il s'agit donc simplement d'appeler la méthode iSempty de cette classe} public void clear () {// l'ensemble réécrit # méthode claire abstractmap.this.clear (); // effacer la valeur clé, c'est juste pour effacer la carte, il s'agit donc simplement d'appeler la méthode claire de cette classe} public boolean contient (objet k) {// le jeu de réécriture # contient la méthode return abstractMap.this.containsKey (k); // juger si SET contient des données K, ce qui signifie si la carte contient la valeur clé, alors appelez simplement la méthode CONTAINSKEY de cette classe}}; keyset = ks; // Attribuez cette collection de jeux personnalisés à la clé de la variable. Lorsque vous appelez à nouveau la méthode de Keyset à l'avenir, car le Setset n'est pas nul, il vous suffit de revenir directement. } return ks;Je pense que c'est une implémentation très intelligente. Bien que cette méthode tourne autour de la valeur clé, elle peut en fait être implémentée en combinaison avec l'entrée sans traverser l'entrée. Dans le même temps, il est mentionné ci-dessus que l'appel de la méthode Iterator de l'entrée #, qui est la meilleure pratique du mode méthode de modèle. Parce que l'entrée n'est pas implémentée dans AbstractMap, mais est laissée à sa sous-classe pour terminer, mais la méthode de la clé peut être implémentée avec un "squelette d'algorithme", qui est le modèle de méthode de modèle.
Collection publique <v> valeurs ()
Pour la méthode des valeurs, vous pouvez vous référer complètement à Keyset. Les deux ont le même effet, donc je ne le répéterai pas ici pour économiser de l'espace.
ensemble de résumé public <entrée <k, v >> entryset ()
Une méthode abstraite est remise à sa sous-classe pour terminer, indiquant que cette méthode n'est pas particulièrement "générale".
booléen public est égal (objet O)
La carte stipule que lorsque la clé et la valeur de chaque paire de valeurs de clé dans la carte correspondent à une par une Dans la méthode, jugez d'abord les conditions simples. Si les références sont égales, revenez vrai directement. Si le paramètre O n'est pas le type de carte, renvoyez-vous directement. Si le nombre des deux cartes est différent, revenez faux directement. Ce n'est qu'alors que la parole sur le tableau d'entrée et comparera si la clé et la valeur de l'entrée correspondent un par un. La méthode est simple, mais cela nous donne une inspiration. Dans le jugement conditionnel, nous devons d'abord juger les simples basiques, puis juger les complexes.
public int hashcode ()
Réécrivez la méthode égaux de la classe d'objets et réécrivez le code de hachage est également nécessaire. L'implémentation de HashCode par AbstractMap consiste à ajouter les valeurs de code de hash de toutes les map.Entry (voici SimpleEntry ou Simple ImmutableEntry) à la fin, et la somme finale est utilisée comme valeur de code de hashcode de MAP.
public String toString ()
Il n'y a rien à dire sur cette méthode, c'est pour éliminer toutes les paires de valeurs clés et utiliser StringBuilder pour les épisser.
Clone d'objet protégé () lève ClonenotsupportEdException
Mettre en œuvre une copie peu profonde, car il s'agit d'une copie peu profonde de l'ensemble de clés et des valeurs variables, empêchant les problèmes causés par les deux copies peu profondes.