1. Introduction à la chaîne, méthodes communes Analyse du code source
2. Analyse de piscine constante de chaîne
Méthodes courantes
égal
garniture
remplacer
concat
diviser
Startwith et Endswith
Sous-chaîne
touppercase () et tolowercase ()
comparaison
Introduction à la chaîne
La classe String est modifiée par Final, ce qui signifie que l'objet String est un immuable, et les programmes simultanés préfèrent les immuables. La classe String implémente les interfaces sérialisables, comparables et CharSequence.
Commencez par un morceau de code:
public void stringTest () {String a = "a" + "b" +1; String b = "AB1"; System.out.println (a == b);}Devinez quel est le résultat? Si votre conclusion est vraie. Ok, ayons un autre code:
public void stringTest () {String a = new String ("AB1"); String b = "AB1"; System.out.println (a == b);}Quel est le résultat? La bonne réponse est fausse.
Voyons comment le code compilé par le compilateur
// le premier code public void stringTest () {String a = "AB1"; String b = "AB1"; System.out.println (a == b);} // le deuxième code public void stringTest () {String a1 = new String ("AB1"); String b = "AB1"; System.out.println (a1 == b);}En d'autres termes, le premier morceau de code a été optimisé pendant la période de compilation car le compilateur a constaté que les effets de "A" + "B" +1 et "AB1" sont les mêmes, et ils sont tous deux composés d'immutables. Mais pourquoi leurs adresses de mémoire sont-elles les mêmes? Si vous y êtes toujours intéressé, jetons un coup d'œil à certains codes source importants de la classe String.
Code source
1. Attributs de chaîne
La classe String contient un réseau de char immuable pour stocker les chaînes, et un hachage variable int est utilisé pour stocker la valeur de hachage calculée.
/ ** La valeur est utilisée pour le stockage des caractères. * / Valeur de char finale privée []; / ** Cache le code de hachage pour la chaîne * / private int hash; // par défaut à 0 / ** Utiliser SerialVersionUID de JDK 1.0.2 pour l'interopérabilité * / private static final SerialVersionUID = -6849794470754667710L;
2. Constructeur de chaîne
// Les constructeurs sans paramètres sont généralement inutiles, car la valeur est une chaîne publique immuable () {this.value = new Char [0];} // Le paramètre est un type de chaîne publique String (String Original) {this.value = original.Value; this.hash = original.hash;} // Le paramètre est un tableau char, utilisez la classe des tableaux dans le package java.utils pour copier la chaîne publique (valeur char []) {this.value = arrays.copyof (valeur, valeur.length);} // commence à partir du poste de dépens Bytes [], int offset, int legth, string charSetName) lève unportdencodingException {if (charSetName == null) throw new NullPointerException ("charSetName"); Checkbounds (octets, décalage, longueur); this.value = stringcoding.decode (charsetName, octets, offset, longueur);} // appelle la chaîne publique (octet octets [], into offset, intylaine, string charsetName) Constructor String (octets bytes [], string charsetName) lance un usupportedEncodException {this (bytes, 0, bytes.Lengon3. Méthodes courantes de chaîne
1.
Boolean est égal (objet anobject) public booléen égaux (objet anobject) {// Si la référence est le même objet, return true if (this == anObject) {return true; } // Si les données de Type String ne sont pas une chaîne, return false if (anObject instanceOf String) {String anotherstring = (string) anObject; int n = value.length; // Si la longueur du tableau char n'est pas égal, renvoyez false if (n == anotherstring.value.length) {char v1 [] = valeur; char v2 [] = anotherstring.value; int i = 0; // juge du caractère unique à l'avant, s'il y a une inégalité, renvoyez false while (n--! = 0) {if (v1 [i]! = V2 [i]) return false; i ++; } // Chaque caractère est égal, retour true return true; }} return false;}String e1 = "GOOD"; String e2 = "bon tous les jours"; e1.equals (e2); // retourne false
1 Tout d'abord, déterminez si le même objet est référencé ==, c'est-à-dire déterminer si les adresses mémoire des deux références sont les mêmes. Si la même chose, il reviendra directement vrai.
2 déterminera si les types sont les mêmes et s'ils sont le même type de données
3 Si le même type est utilisé, la longueur du réseau de caractères converti est la même.
4 Comparez si chaque personnage est le même de l'arrière à l'avant
Ordonnance de jugement =》 1. Adresse mémoire 2. Type de données 3. Longueur du tableau des caractères 4. Comparaison unique de caractères
2. Compareto
int compareto (String anotherstring) public int compareto (String anotherstring) {// la longueur de la chaîne du propre objet Len1 int len1 = value.length; // la longueur de la chaîne de l'objet comparé Len2 = anotherstring.value.length; // la valeur minimale de la longueur de deux chaînes lim int lim = math.min (Len1, Len2); char v1 [] = valeur; char v2 [] = anotherstring.value; int k = 0; // Du premier caractère de la valeur à la longueur minimale LIM, si les caractères ne sont pas égaux, retournez lui-même (caractères où les objets ne sont pas égaux - les caractères qui sont comparés) tandis que (k <lim) {char c1 = v1 [k]; char c2 = v2 [k]; if (c1! = c2) {return c1 - c2; } k ++; } // Si les fronts sont tous égaux, retourne (Longueur elle-même - longueur de l'objet comparé) Return Len1 - Len2;}String co1 = "Hello"; String co2 = "Hello"; String Co3 = "Hello You"; System.out.println (co1.compareto (CO2)); // 0System.out.println (co1.compareto (CO3)); // -4
Cette méthode est écrite ingénieusement, et vous pouvez juger la taille du personnage à partir de 0 en premier.
Si la comparaison entre les deux objets peut comparer les caractères est toujours égale, la longueur de l'objet comparé est directement retournée. Si la longueur des deux cordes est égale, le retour est 0, ce qui juge intelligemment les trois situations.
3.Hashcode
int hashcode () public int hashcode () {int h = hash; // Si le hachage n'a pas été calculé et que la chaîne n'est pas vide, alors le calcul de code de hashcode est effectué si (h == 0 && value.length> 0) {char Val [] = valeur; // Processus de calcul // S [0] * 31 ^ (n-1) + s [1] * 31 ^ (n-2) + ... + s [n-1] pour (int i = 0; i <value.length; i ++) {h = 31 * h + val [i]; } // Affectation de hash Hash = H; } retour h;}String a = "Toyou"; char Val [] = a.tocharArray (); char c1 = 't'; char c2 = 'a'; int f = c1; int e = c2; System.out.println (e); // 97 asystem.out.println (f); // 116 tsystem.out.println (31 * val [0]); // 3596System.out.println (31 * C1); // 3596 // Calcul de code de hash car les caractères de char peuvent être automatiquement convertis en forme INT correspondante
La classe String remplace la méthode HashCode et la méthode HashCode dans l'objet est un appel natif.
Le hachage de la classe String est calculé à l'aide de polynômes. Nous pouvons obtenir complètement le même hachage à travers différentes chaînes. Par conséquent, le code de hash de deux objets de chaîne est le même, ce qui ne signifie pas que les deux chaînes sont les mêmes.
Le code hashcode du même objet de chaîne doit être le même, mais le HashCode est le même, pas nécessairement le même objet
4. Startswith
booléen startSwith (String Prefix, int toffset) public booléen startSwith (préfixe de chaîne, int toffset) {char ta [] = valeur; int à = toffset; char pa [] = prefix.value; int po = 0; int pc = prefix.value.length; // Remarque: Toffset peut être proche -1 >>> 1. // Si l'adresse de départ est inférieure à 0 ou (adresse de départ + longueur de l'objet comparé) est supérieure à la longueur de l'objet propre, return false if ((toffset <0) || (toffset> value.length - pc)) {return false; } // Comparez de la fin de l'objet comparé while (--pc> = 0) {if (ta [to ++]! = Pa [po ++]) {return false; }} return true;} public boolean startSwith (String Prefix) {return startSwith (prefix, 0);} public boolean endWith (string suffixe) {return startSwith (suffixe, value.length - suffix.value.length);} String d = "www.58fxp.com"; System.out.println (d.startswith ("www")); // true system.out.println (d.endswith ("com")); // vraiLe démarrage et la fin de la comparaison sont des méthodes courantes. Par exemple, lorsque vous jugez si une chaîne provient du protocole HTTP ou juge initialement si un fichier est un fichier MP3, vous pouvez utiliser cette méthode pour comparer.
5.Concat
String Concat (String Str) public String Concat (String Str) {int autre autre = str.length (); // Si la chaîne ajoutée est vide, renvoyez l'objet lui-même if (autrelen == 0) {renvoie ceci; } int len = value.length; char buf [] = arrays.copyof (valeur, len + autrelen); str.getchars (buf, len); retourner une nouvelle chaîne (buf, true);} String cat = "beaucoup"; String newcat = cat.concat ("oui"); // beaucoup ouiLa méthode Concat est également l'une des méthodes couramment utilisées. Il détermine d'abord si la chaîne ajoutée est vide pour décider de créer un nouvel objet.
1 Si la longueur du caractère épissé est 0, revenez directement à l'objet de caractère d'origine
2 Les caractères épissés ne sont pas vides et renvoient un nouvel objet de caractère
Déterminez la longueur du caractère pour générer un nouvel objet
6. Replace
String remplace (char oldchar, char newchar) public String remplace (char oldchar, char newchar) {// comparer les anciennes et nouvelles valeurs d'abord if (oldchar! = NewChar) {int len = value.length; int i = -1; char [] val = valeur; / * Évitez GetField Opcode * / // Trouvez la position où l'ancienne valeur apparaît d'abord while (++ i <len) {if (val [i] == oldchar) {break; }} // De cette position, jusqu'à la fin, remplacez l'ancienne valeur qui apparaît par la nouvelle valeur if (i <len) {char buf [] = new char [len]; pour (int j = 0; j <i; j ++) {buf [j] = val [j]; } while (i <len) {char c = val [i]; buf [i] = (c == oldchar)? Newchar: C; i ++; } return new String (buf, true); }} Renvoyez ceci;} String r1 = "Comment faites-vous"; String r2 = r1.replace ("do", "is"); system.out.println (r2); // comment vas-tuCette méthode a également une certaine intelligence, comme découvrir où l'ancienne valeur apparaît au début, ce qui fait gagner du temps de comparaison.
La méthode Replace (String Oldstr, String Newstr) est jugée par des expressions régulières.
7.Trim
String Trim () public String Trim () {int len = value.length; int st = 0; char [] val = valeur; / * Évitez GetField Opcode * / // Trouvez la position sans espaces devant la chaîne while ((st <len) && (val [st] <= '')) {st ++; } // Trouvez la position sans espaces à la fin de la chaîne while ((st <len) && (val [len - 1] <= '')) {len--; } // S'il n'y a pas d'espaces devant et après, renvoyez la chaîne elle-même ((st> 0) || (len <value.length))? substrat (st, len): ceci;} String t1 = "public void"; // un espace devant et après System.out.println ("T1:" + t1.length ()); // 13 avec chaîne de longueur d'espace t2 = t1.trim (); System.out.println ("T2:" + T2.Length ()); // 11 Retirez le Système Space.out.println (T2);8.Inter
String inter () public native string inter ();
String dd = new String ("bb"). Intern ();La méthode Ntern est un appel natif, et sa fonction est de trouver des objets de valeur égale via la méthode égaux dans le pool constant dans la zone de la méthode.
Si vous n'êtes pas trouvé, ouvrez un espace dans le pool constant pour stocker la chaîne et renvoyez la référence à la chaîne correspondante. Sinon, renvoyez directement la référence à l'objet String existe déjà dans le pool constant.
Vous pouvez également forcer l'objet de caractère créé pour la nouvelle méthode pour voir si le pool constant existe déjà.
Mettez le deuxième code dans l'introduction
// String a = new String ("AB1"); // Changez vers String A = new String ("AB1"). Intern ();Le résultat est vrai, car l'adresse indiquée par A provient du pool constant, et la constante de chaîne pointée par B appellera cette méthode par défaut, donc A et B pointent les deux vers le même espace d'adresse.
int hash32 () Transient privé int hash32 = 0; int hash32 () {int h = hash32; if (0 == h) {// Race de données inoffensive sur hash32 ici. H = Sun.Misc.Hashing.Murmur3_32 (HASHing_seed, Value, 0, Value.Length); // Assurez-vous que le résultat n'est pas nul pour éviter de recalancer H = (0! = H)? H: 1; hash32 = h; } retour h;}Dans JDK1.7, lorsque la classe de chaîne est utilisée comme clé, la classe de collecte liée au hash n'utilise plus la méthode HashCode pour des données discrètes, mais utilise la méthode Hash32.
Cette méthode utilise l'heure actuelle du système, l'adresse de la classe de chaînes, l'adresse de la classe du système, etc. comme facteurs pour calculer la graine de hachage. Grâce à la graine de hachage, une valeur int 32 bits est obtenue par la graine de hachage.
public int Length () {return value.length;} public String toString () {return this;} public boolean isEmpty () {return value.length == 0;} public char Charat (int index) {if ((index <0) || (index> = value.length)) {lance new StringIndexoutOfBoundSexception (index); } valeur de retour [index];}Ce qui précède est quelques méthodes communes simples.
Résumer
Les objets de chaîne sont des types immuables. Méthodes de chaîne avec type de retour chaîne Retour chaque fois qu'un nouvel objet String est renvoyé, à l'exception de certaines conditions spécifiques de certaines méthodes pour se retourner.
Trois façons de comparer les objets de chaîne:
== Comparaison de la mémoire: comparez directement les valeurs de mémoire pointées par les deux références, qui sont exactes, concises et simples.
Égalise la comparaison des valeurs de chaîne: comparez si les valeurs littérales des deux objets référencés sont égaux.
Comparaison de la chaîne de la chaîne HashCode Numericalisation: numéricalisation des chaînes. Les deux codes de hash référencés sont les mêmes, et la mémoire n'est pas garantie d'être la même, et les valeurs littérales ne sont pas garanties d'être les mêmes.
Idée de conception de la piscine constante de cordes
1. Intention d'origine de conception de piscine constante de cordes
Chaque chaîne est un objet de chaîne et les chaînes seront fréquemment utilisées dans le développement du système. S'il est créé et détruit comme d'autres objets, cela affectera grandement les performances du programme.
Afin d'améliorer les performances et de réduire les frais généraux de mémoire, JVM optimise lors de l'instanciation des chaînes.
Une piscine constante à cordes est ouverte pour les chaînes, similaire à une zone de cache
Lors de la création d'une constante de chaîne, déterminez d'abord s'il existe le pool constant de chaîne.
La chaîne renvoie une instance référencée, n'existe pas, instancier la chaîne et la met dans le pool.
Réalisez les bases
La base de la mise en œuvre de cette optimisation est que chaque constante de chaîne est une constante finale modifiée, il n'est donc pas nécessaire de se soucier des conflits de données dans le pool constant.
Il y a un tableau dans le pool constant de chaîne global créé par l'instance d'exécution, qui maintient toujours une référence pour chaque objet de chaîne unique dans le pool, ce qui signifie qu'ils se réfèrent toujours aux objets dans le pool constant de chaîne, de sorte que ces chaînes dans le pool constant ne seront pas collectées par le collecteur de déchets.
Tas, pile, zone de méthode
Comprendre les piscines constantes de cordes, regardez d'abord la zone de la méthode de pile
tas
Ce qui est stocké est un objet, chaque objet contient une classe correspondante
Le JVM n'a qu'une seule zone de tas et est partagé par tous les fils. Il n'y a pas de types de base et de références d'objets dans le tas, mais seulement l'objet lui-même
Les objets sont collectés par le collecteur des ordures, de sorte que la taille et le cycle de vie ne doivent pas être déterminés
Empiler
Chaque thread contient une zone de pile, qui stocke uniquement les objets de type de données de base et les références d'objets personnalisées.
Les données (type primitif et référence d'objet) dans chaque pile sont privées
La pile est divisée en trois parties: la zone variable de type de base, le contexte de l'environnement d'exécution et la zone d'instructions de fonctionnement (stockage d'instructions de fonctionnement)
La taille des données et le cycle de vie sont certains, et lorsqu'aucune référence ne pointe vers ces données, les données disparaîtront.
Zone de méthode
Les zones statiques, comme des tas, sont partagées par tous les fils
La zone de méthode contient des éléments qui sont toujours uniques dans l'ensemble du programme, tels que la classe et les variables statiques;
String Pool constant
La piscine constante de cordes existe dans la zone de la méthode
Code: la zone de pile de la méthode des magasins Stores Strings
String str1 = "ABC"; String str2 = "ABC"; String str3 = "ABC"; String str4 = new String ("ABC"); String str5 = new String ("ABC");Questions d'entrevue
String str4 = new String ("ABC") Combien d'objets sont créés?
Split: str4 =, new String (), "ABC"
Vous pouvez créer un nouvel objet via une nouvelle méthode. La nouvelle méthode crée un objet instancié et n'ira pas au pool constant pour découvrir s'il existe déjà. Tant que nouveau, un nouvel objet sera instancié.
"ABC" Chaque chaîne est un objet de chaîne. S'il n'y a pas dans le pool constant, un nouvel objet sera créé et mis dans le pool constant. Sinon, la référence de l'objet sera retournée.
Attribuez l'adresse de l'objet à STR4 et créez une référence
Donc, s'il n'y a pas de littéral "ABC" dans le pool constant, créez deux objets, sinon créez un objet et créez une référence
String str1 = new String ("a" + "b"); Combien d'objets seront créés? String str2 = new String ("ABC") + "ABC"; Combien d'objets seront créés?
L'analyse complète ci-dessus du code source de chaîne Java et du pool constant de chaîne est tout le contenu que je partage avec vous. J'espère que vous pourrez vous faire référence et j'espère que vous pourrez soutenir Wulin.com plus.