Il peut être prouvé que l'opération sur chaîne est le comportement le plus courant en programmation informatique.
Tout d'abord, nous devons préciser que String n'est pas un type de données de base, mais un objet, et c'est un objet immuable. En regardant le code source, vous constaterez que la classe String est finale (bien sûr, elle ne peut pas être héritée), et en consultant la documentation du JDK, vous constaterez que presque chaque opération qui modifie un objet String crée en fait un nouvel objet String. .
La chaîne est un objet, donc avant initialisation, sa valeur est nulle Il faut mentionner "", null, new String() ici La différence. entre les trois. null signifie que la chaîne n'est pas encore nouvelle, ce qui signifie que la référence à l'objet n'a pas encore été créée et qu'aucun espace mémoire ne lui a été alloué. Cependant, "" et new String() indiquent qu'elle est nouvelle. , mais il est vide en interne, mais il a été créé. Une référence à un objet nécessite une allocation d'espace mémoire. Par exemple : un verre vide, tu ne peux pas dire qu'il n'y a rien dedans, car il y a de l'air à l'intérieur, bien sûr tu peux aussi en faire un vide, nul et " ", New String () est la même chose que le vide et l'air.
Il y a un endroit très spécial dans la chaîne, c'est-à-dire le pool de cordes. Chaque fois nous créons un objet chaîne, nous vérifions d'abord s'il existe une chaîne avec une valeur nominale égale dans le pool de chaînes. S'il y en a, il ne la créera pas et remettra directement la référence à l'objet dans le pool de chaînes. Créez-le, puis placez-le dans le pool de chaînes et renvoyez une référence à l'objet nouvellement créé. Ce mécanisme est très utile car il peut améliorer l'efficacité et réduire l'utilisation de l'espace mémoire. Par conséquent, il est recommandé d'utiliser l'affectation directe (c'est-à-dire lors de l'utilisation de chaînes). ). String s="aa"), un nouvel objet String (c'est-à-dire String s = nouvelle chaîne ("aa")).
L'utilisation des ficelles n'est rien de plus que ces aspects :
1. Comparaison de chaînes
equals() ------ Déterminez si le contenu est le même.
compareTo() ------ Déterminez la relation de taille des chaînes.
compareToIgnoreCase(String int) ------Ignorer la casse des lettres lors de la comparaison.
equalsIgnoreCase() ------ Déterminez si le contenu est le même tout en ignorant la casse.
ReagionMatches () ----------------------------- --------- veuillez vous référer à l'API pour plus de détails.
2. Recherche de chaîne
charAt(int index ) ------Renvoie le caractère à la position d'index spécifiée, la plage d'index commence à 0.
.
Indexof (String Str, int FROMINDEX -----------------------); ----------------------------------- commencez à récupérer STR à partir du caractère FROMINDEX de la chaîne.lastIndexOf(String str)------Trouver la position de la dernière occurrence.
.
starWith(String prefix, int toffset)-----Test si la sous-chaîne de cette chaîne à partir de l'index spécifié commence par le préfixe spécifié.
starWith(String prefix)------Testez si cette chaîne commence par le préfixe spécifié.
endsWith(Suffixe de chaîne)------Testez si cette chaîne se termine par le suffixe spécifié.
3. Interception de chaînes
public String subString(int BeginIndex)------Renvoie une nouvelle chaîne, qui est une sous-chaîne de cette chaîne.
public String subString(int BeginIndex, int EndIndex)------La chaîne renvoyée est une chaîne commençant par BeginIndex jusqu'à EndIndex-1.
4. Remplacement de chaîne
remplacement de chaîne publique (char oldChar, char newChar).
public String replace (CharSequence target, CharSequence replacement)------Remplacez la sous-séquence etarget d'origine par la séquence de remplacement et renvoyez une nouvelle chaîne.
public String replaceAll (String regex, String replacement)------Utilisez des expressions régulières pour faire correspondre les chaînes. Notez que le premier paramètre de replaceAll est une expression régulière et j'en ai beaucoup souffert.
5. Pour plus de méthodes, veuillez vous référer à l'API
StringBuffer et Strings sont tous utilisés pour stocker des chaînes, mais en raison de leurs implémentations internes différentes, les plages qu'ils utilisent sont différentes. Pour StringBuffer, lorsqu'il traite une chaîne, s'il la modifie, il ne génère pas de nouvel objet chaîne. , c'est donc mieux que String en termes d'utilisation de la mémoire.
En fait, de nombreuses méthodes de StringBuffer sont similaires à celles de la classe String, et les fonctions qu'elles représentent sont presque exactement les mêmes, sauf que StringBuffer se modifie lorsqu'il est modifié. , tandis que la classe String génère un nouvel objet, ce qui constitue la plus grande différence entre eux.
En même temps, StringBuffer ne peut pas être initialisé en utilisant =. Il doit générer une instance StringBuffer, ce qui signifie que vous devez l'initialiser via sa méthode de construction.
En termes d'utilisation de StringBuffer, il se concentre davantage sur les modifications apportées aux chaînes, telles que l'ajout, la modification et la suppression. Les méthodes correspondantes sont : <.>
1. append() : ajoute le contenu spécifié à la fin de l'objet StringBuffer actuel, similaire à la connexion de chaînes, où le contenu de l'objet StringBuffer changera.
2. insert : Cette méthode insère principalement du contenu dans l'objet StringBuffer.
3. delete : Cette méthode est principalement utilisée pour supprimer le contenu de l'objet StringBuffer.
StringBuilder est également un objet chaîne mutable La différence avec. StringBuffer est qu'il n'est pas sécurisé pour les threads. Sur cette base, sa vitesse est généralement plus rapide que StringBuffer. Comme StringBuffer, les principales opérations de StringBuider sont également les méthodes append et insert. Les deux méthodes convertissent efficacement les données données en chaîne, puis ajoutent ou insèrent les caractères de cette chaîne dans le générateur de chaînes. Ce qui précède présente simplement String, StringBuffer et StringBuilder. En fait, pour ces trois-là, nous devrions prêter plus d'attention aux différences qu'ils ne voient que. en clarifiant la différence entre eux, vous pouvez mieux les utiliser. Regardons d'abord le tableau suivant : Je ne sais pas très bien si String est thread-safe ici. La raison : String l'est. immuable, donc tout Il est impossible de modifier sa valeur par n'importe quelle opération. Il est difficile de dire s'il existe une sécurité des threads ? Mais si vous insistez sur la sécurité des fils de discussion, parce que le contenu est immuable, il est toujours sûr. En termes d'utilisation, puisque String doit générer un nouvel objet à chaque fois qu'il est modifié, il est préférable de choisir StringBuffer ou StringBuilder pour les chaînes qui ont souvent besoin pour modifier leur contenu. Pour StringBuffer, chaque opération est effectuée sur l'objet StringBuffer lui-même et ne génère pas de nouveaux objets. Par conséquent, StringBuffer est particulièrement adapté aux situations où le contenu de la chaîne change fréquemment. Mais toutes les opérations sur les chaînes String ne seront pas plus lentes que StringBuffer. Dans certains cas particuliers, la concaténation des chaînes String sera analysée par la JVM dans l'épissage d'objets StringBuilder. , dans ce cas, String est plus rapide que StringBuffer. Tels que : String name = ”I ” ” suis ” ” chenssy ” ; StringBuffer name = new StringBuffer(”I ”).append(” am ”).append(” chenssy ”); Pour ces deux méthodes, Vous constaterez que la première méthode est beaucoup plus rapide que la deuxième méthode et que l'avantage de StringBuffer est ici perdu. La vraie raison est que la JVM a fait quelques optimisations. En fait, String name = "I" "am" "chenssy"; aux yeux de la JVM, c'est String name = "I am chenssy"; cette méthode est vraiment efficace. Cela ne prend pas de temps. Mais si nous y ajoutons un objet String, la JVM construira l'objet String conformément à la spécification d'origine. Les scénarios dans lesquels ces trois sont utilisés sont résumés comme suit (référence : "Writing Quality Code : 151 Suggestions for Improving Java Programs") : 1, String : Vous pouvez utiliser la classe String dans la scène où la chaîne n'est pas souvent modifiée, comme : une déclaration de constante, une petite quantité d'opérations variables, etc. 2. StringBuffer : Si vous effectuez fréquemment des opérations de chaîne (épissage, remplacement, suppression, etc.) et exécutez dans un environnement multithread, vous pouvez envisager Utilisez StringBuffer, comme l'analyse XML, l'analyse et l'encapsulation des paramètres HTTP, etc. 3. StringBuilder : si vous effectuez fréquemment des opérations sur les chaînes (épissage, remplacement, suppression, etc.) et que vous les exécutez dans un environnement multithread, vous pouvez envisager Utilisez StringBuffer, comme l'assemblage d'instructions SQL, l'encapsulation JSON, etc. (il semble que j'utilise également |StringBuffer pour ces deux-là). Pour plus d'informations sur les différences entre eux, veuillez vous référer à : http://www.php.cn/. Je n’ajouterai pas de bruit inutile et inutile. Pour les chaînes, nous avons souvent besoin de les assembler. Trois méthodes d'assemblage ont été ajoutées en Java : les méthodes , concat() et append(). Quelle est la différence entre ces trois ? Regardez d'abord l'exemple suivant : Il ressort des résultats d'exécution ci-dessus que append() est le plus rapide, suivi de concat() et est le plus lent. Veuillez consulter la répartition ci-dessous pour les raisons : 🎜> str = new StringBuilder(str).append("b").toString(); et toString(), 100 000 objets StringBuilder sont créés ici, et ils doivent être convertis en String à chaque fois. N'est-ce pas lent ?
Grâce à l'analyse ci-dessus, nous devons choisir la méthode d'épissage de chaîne appropriée à l'endroit approprié, mais il n'est pas nécessaire de choisir append() et concat( ), la raison est que, selon nos habitudes de programmation, nous n'envisagerons d'utiliser les méthodes append() et concat() que si cela peut vraiment améliorer l'efficacité de notre système. En même temps, je ne les utilise vraiment pas. beaucoup. Grâce à la méthode concat().
3. StringBuilder
4. Utilisez String, StringBuffer, correctement StringBuilder
5. Méthode d'épissage des cordes
public class StringTest {
/**
* @desc 使用+、concat()、append()方法循环10W次
* @author chenssy
* @data 2013-11-16
* @param args
* @return void
*/
public static void main(String[] args) {
//+
long start_01 = System.currentTimeMillis();
String a = "a";
for(int i = 0 ; i < 100000 ; i++){
a += "b";
}
long end_01 = System.currentTimeMillis();
System.out.println(" + 所消耗的时间:" + (end_01 - start_01) + "毫米");
//concat()
long start_02 = System.currentTimeMillis();
String c = "c";
for(int i = 0 ; i < 100000 ; i++){
c = c.concat("d");
}
long end_02 = System.currentTimeMillis();
System.out.println("concat所消耗的时间:" + (end_02 - start_02) + "毫米");
//append
long start_03 = System.currentTimeMillis();
StringBuffer e = new StringBuffer("e");
for(int i = 0 ; i < 100000 ; i++){
e.append("d");
}
long end_03 = System.currentTimeMillis();
System.out.println("append所消耗的时间:" + (end_03 - start_03) + "毫米");
}
}
------------
Output:
+ 所消耗的时间:19080毫米
concat所消耗的时间:9089毫米
append所消耗的时间:10毫米
public class StringTest {
/**
* @desc 使用+、concat()、append()方法循环10W次
* @author chenssy
* @data 2013-11-16
* @param args
* @return void */
public static void main(String[] args) { //+
long start_01 = System.currentTimeMillis();
String a = "a"; for(int i = 0 ; i < 100000 ; i++){
a += "b";
} long end_01 = System.currentTimeMillis();
System.out.println(" + 所消耗的时间:" + (end_01 - start_01) + "毫米");
//concat()
long start_02 = System.currentTimeMillis();
String c = "c"; for(int i = 0 ; i < 100000 ; i++){
c = c.concat("d");
} long end_02 = System.currentTimeMillis();
System.out.println("concat所消耗的时间:" + (end_02 - start_02) + "毫米");
//append
long start_03 = System.currentTimeMillis();
StringBuffer e = new StringBuffer("e"); for(int i = 0 ; i < 100000 ; i++){
e.append("d");
} long end_03 = System.currentTimeMillis();
System.out.println("append所消耗的时间:" + (end_03 - start_03) + "毫米");
}
}------------Output: + 所消耗的时间:19080毫米
concat所消耗的时间:9089毫米
append所消耗的时间:10毫米
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
char buf[] = new char[count + otherLen];
getChars(0, count, buf, 0);
str.getChars(0, otherLen, buf, count);
return new String(0, count + otherLen, buf);
}
Ceci est le code source de concat() , cela ressemble à une copie numérique. Nous savons que le traitement du tableau est très rapide, mais comme la méthode se termine comme ceci : return new String(0, count otherLen, buf); cause profonde de sa lenteur. public synchronized StringBuffer append(String str) { super.append(str); return this;
}
La méthode append() de StringBuffer consiste à utiliser directement la méthode append() de la classe parent AbstractStringBuilder Le code source de ceci. La méthode est la suivante : public AbstractStringBuilder append(String str) {
if (str == null) str = "null";
int len = str.length();
if (len == 0) return this;
int newCount = count + len;
if (newCount > value.length)
expandCapacity(newCount);
str.getChars(0, len, value, count);
count = newCount;
return this;
}
Le tableau est traité, allongé , puis copié, mais veuillez noter qu'il ne renvoie pas une nouvelle chaîne à la fin, mais se renvoie lui-même. En d'autres termes, au cours de cette boucle de 100 000 fois, il ne génère pas de nouvel objet chaîne.