D'une manière ou d'une autre, j'ai décidé de lire également la source JDK. Cela dit, je n'ai pas le temps de lire attentivement chaque ligne, alors je l'ai lu brièvement et j'ai trouvé ce code. La dernière fois j'ai lu la source de Long, c'est donc String.
La classe String est une classe de chaîne. Depuis que nous avons créé Byte, Short, Integer et Long, on peut dire que String est également une classe wrapper pour char []. Eh bien, le terrain.
String.java
private final char value[];
private int hash; // Default to 0
public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator();
Il y a char [] qui est le corps de la chaîne. hash est attribué uniquement dans le constructeur suivant. Sinon, il reste 0.
String.java
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
Calculé lorsque la longueur de la chaîne est supérieure à 0 et que le hachage est égal à 0 lorsque la méthode hashCode est appelée. Lorsque la valeur de hachage calculée par hasard est 0, je pense qu'elle ne devrait pas être calculée à chaque fois, mais c'est peu probable.
String.java
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
Il y avait une constante appelée CASE_INSENSITIVE_ORDER. Je me suis demandé si c'était possible récemment, mais c'était à partir du JDK 1.2.
La méthode length renvoie la longueur. C-like strlen recherche jusqu'à NULL caractères à chaque fois, mais java ne renvoie que la taille du tableau. Cela signifie que la valeur garantit la taille parfaite. Eh bien, c'est immuable, vous n'avez donc pas besoin de marge.
String.java
public int length() {
return value.length;
}
IsEmpty a été ajouté depuis JDK 1.6.
String.java
public boolean isEmpty() {
return value.length == 0;
}
Le contenu est le même que length () == 0, mais c'est une méthode très java qui peut être jugée par le type booléen sans comparer la magnitude de la valeur numérique.
charAt est une méthode pour obtenir un caractère à la fois, et toCharArray est une méthode pour obtenir un lot de tableaux.
String.java
public char charAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index];
}
public char[] toCharArray() {
// Cannot use Arrays.copyOf because of class initialization order issues
char result[] = new char[value.length];
System.arraycopy(value, 0, result, 0, value.length);
return result;
}
charAt ne récupère les éléments qu'en indexant le tableau, mais toCharArray sécurise un autre tableau de la même taille et le copie. Sauf raison particulière, il est préférable d'accéder avec charAt en se tournant vers length () avec l'instruction for.
Au fait, j'ai vu dans les sources d'autres personnes que vous pouvez le diviser en une seule chaîne de caractères avec str.split ("");, mais arrêtez-le comme ceci. Cela signifie que vous pouvez créer des instances String uniquement pour les types de caractères contenus dans la chaîne.
Il existe une méthode interne. Pour être honnête, j'aimerais que vous arrêtiez de faire ça. L'implémentation est une méthode native. J'ai l'impression de faire la valeur de référence en interne.
String.java
public native String intern();
Comment utiliser stag ...
Main.java
public static void main(String[] args) {
String s01 = "abc";
String s02 = "abcdef".substring(0, 3);
System.out.println(s01 == s02);
System.out.println(s01.equals(s02));
String s03 = s02.intern();
System.out.println(s01 == s03);
System.out.println(s01.equals(s03));
}
Quand tu cours ...
false
true
true
true
La valeur de référence est différente lorsque la sous-chaîne est utilisée, mais la valeur de référence est la même lorsque intern est utilisé.
Voici la méthode égale,
String.java
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
Faites attention à ceci == anObject au début. Plutôt que d'écrire toujours l'opérateur de comparaison == en partant du principe que tout est interne, si vous l'écrivez en égal pour le moment, ce sera plus rapide s'il est interne et de la même instance.
Avec égal, la boucle est interrompue à différents points lorsque les longueurs de chaîne sont différentes ou comparées depuis le début, mais le traitement est appliqué lorsque le dernier caractère est différent ou la même chaîne. C'est donc le plus rapide à comparer par valeur de référence, mais d'une manière ou d'une autre, il semble efficace de renvoyer false s'il ne correspond pas en comparant avec hashCode après avoir comparé la longueur. Si hashCode n'est pas calculé, il bouclera jusqu'à 2 fois.
indexOf existe depuis longtemps, mais si vous vous demandez pourquoi l'argument est int ch ...
String.java
public int indexOf(int ch, int fromIndex) {
final int max = value.length;
if (fromIndex < 0) {
fromIndex = 0;
} else if (fromIndex >= max) {
// Note: fromIndex might be near -1>>>1.
return -1;
}
if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
// handle most cases here (ch is a BMP code point or a
// negative value (invalid code point))
final char[] value = this.value;
for (int i = fromIndex; i < max; i++) {
if (value[i] == ch) {
return i;
}
}
return -1;
} else {
return indexOfSupplementary(ch, fromIndex);
}
}
private int indexOfSupplementary(int ch, int fromIndex) {
if (Character.isValidCodePoint(ch)) {
final char[] value = this.value;
final char hi = Character.highSurrogate(ch);
final char lo = Character.lowSurrogate(ch);
final int max = value.length - 1;
for (int i = fromIndex; i < max; i++) {
if (value[i] == hi && value[i + 1] == lo) {
return i;
}
}
}
return -1;
}
Oh, supportait-il les paires de substitution? L'indexOfSupplementary recherche chacun des deux caractères, mais la première moitié est U + D800 à U + DBFF et la seconde moitié est U + DC00 à U + DFFF.
Recherchez simplement lastIndexOf à l'arrière et il existe une méthode pour les paires de substitution appelée lastIndexOfSupplementary. Il semble que JDK 1.5 soit compatible avec les paires de substitution. Il n'y avait pas de MIN_SUPPLEMENTARY_CODE_POINT dans la source du JDK 1.4. Depuis JDK 1.4, l'argument de indexOf est int ch. Ce genre de chose est incroyable.
Je ne sais pas s'il y a des gens dans le monde qui écrivent "abc" .toString () ...
String.java
public String toString() {
return this;
}
Revenez.
Je ne sais pas si la classe String est une bibliothèque d'exécution ou une partie d'une spécification de langage. Par exemple, le constructeur par défaut est ...
String.java
public String() {
this.value = "".value;
}
Recommended Posts