1. Introducción a la cadena, análisis de código fuente de métodos comunes
2. Análisis de piscina constante de cadena
Métodos comunes
iguales
recortar
reemplazar
concatismo
dividir
Inicio con
Subconocencia
toupperCase () y tOlowercase ()
comparación
Introducción a la cuerda
La clase de cadena se modifica por final, lo que significa que el objeto de cadena es un inmutable y los programas concurrentes prefieren inmutables. La clase de cadena implementa las interfaces serializables, comparables y de caracteres.
Comience con un código:
public void StringTest () {String a = "A"+"B" +1; Cadena B = "AB1"; System.out.println (a == b);}¿Adivina cuál es el resultado? Si su conclusión es cierta. Ok, tengamos otro código:
public void StringTest () {String a = new String ("AB1"); Cadena B = "AB1"; System.out.println (a == b);}¿Cuál es el resultado? La respuesta correcta es falsa.
Veamos cómo el código compilado por el compilador
// El primer código public void stringTest () {String a = "AB1"; Cadena B = "AB1"; System.out.println (a == b);} // El segundo código public void StringTest () {String a1 = new String ("AB1"); Cadena B = "AB1"; System.out.println (a1 == b);}En otras palabras, la primera pieza de código se ha optimizado durante el período de compilación porque el compilador descubrió que los efectos de "A"+"B" +1 y "AB1" son los mismos, y ambos están compuestos de inmutables. Pero, ¿por qué sus direcciones de memoria son las mismas? Si todavía está interesado en esto, echemos un vistazo a algunos códigos fuente importantes de la clase de cadena.
Código fuente
1. Atributos de cadena
La clase de cadena contiene una matriz de caracteres inmutables para almacenar cadenas, y se utiliza un hash variable int para almacenar el valor hash calculado.
/** El valor se utiliza para el almacenamiento de personajes. */Valor de caracteres finales privados [];/** Cache El código hash para la cadena*/private int hash; // predeterminado a 0/** Use SerialVersionUid de JDK 1.0.2 para la interoperabilidad*/privado estático final Long SerialVersionUid = -6849794470754677710L;
2. Constructor de cadenas
// Los constructores sin parámetros son generalmente inútiles, porque el valor es una cadena pública inmutable () {this.value = new Char [0];} // El parámetro es un tipo de cadena de cadena (String original) {this.value = original.value; this.hash = original.hash;}//The parameter is a char array, use the Arrays class in the java.utils package to copy public String(char value[]) { this.value = Arrays.copyOf(value, value.length);}// Start from the offset position in the bytes array, encode the bytes of length in the charsetName format and copy it to valuepublic String(byte bytes [], int offset, int long, string charsetName) lanza UnsPportedEncodingException {if (CharSetName == NULL) Lanza nueva NullPointerException ("CharSetName"); checkbounds (bytes, desplazamiento, longitud); this.Value = StringCoding.Decode (charsetName, bytes, offset, longitud);} // llame a la cadena public (byte bytes [], int offset, int long, string charsetName) constructor public string (bytes bytes [], string charsetNeTs) lanza unrupportedEncodingException {this (bytes, 0, bytes.ll longitud;3. Métodos comunes de cadena
1. Iguales
boolean iguales (objeto anobject) public boolean iguales (objeto anobject) {// Si la referencia es el mismo objeto, return true if (this == anobject) {return true; } // Si los datos de la cadena de tipo no son cadena, return false if (anobject instanceOf string) {String anothString = (string) anobject; int n = value.length; // Si la longitud de la matriz de char no es igual, devuelva falso if (n == anotherstring.value.length) {char v1 [] = valor; char v2 [] = anotherstring.value; int i = 0; // juzga desde el carácter único al frente, si hay alguna desigualdad, devuelve falso mientras (n--! = 0) {if (v1 [i]! = V2 [i]) return false; i ++; } // Cada personaje es igual, return verdadero return verdadero; }} return false;}Cadena e1 = "bueno"; string e2 = "bueno todos los días"; e1.equals (e2); // devolver falso
1 Primero, determine si se hace referencia al mismo objeto ==, es decir, determine si las direcciones de memoria de las dos referencias son las mismas. Si es lo mismo, volverá directamente verdadero.
2 determinará si los tipos son los mismos y si son el mismo tipo de datos
3 Si se usa el mismo tipo, la longitud de la matriz de caracteres convertida es la misma.
4 Compare si cada personaje es el mismo desde la parte posterior al frente
Orden de juicio =》 1. Dirección de memoria 2. Tipo de datos 3. Longitud de matriz de caracteres 4. Comparación de caracteres individuales
2. Compareto
int Compareto (String AnothString) public int Compareto (String anothString) {// La longitud de la cadena del propio objeto Len1 int len1 = value.length; // La longitud de la cadena del objeto comparado Len2 = anotherstring.value.length; // El valor mínimo de la longitud de dos cadenas lim int lim = math.min (len1, len2); char v1 [] = valor; char v2 [] = anotherstring.value; int k = 0; // Desde el primer carácter del valor hasta la longitud mínima LIM, si los caracteres no son iguales, return (caracteres donde los objetos no son iguales, los caracteres que se comparan) mientras (k <lim) {char c1 = v1 [k]; char c2 = v2 [k]; if (c1! = c2) {return c1 - c2; } k ++; } // Si los frentes son iguales, return (en sí mismo la longitud del objeto que se compara) return Len1 - len2;}Cadena co1 = "hello"; string co2 = "hello"; string co3 = "hello you"; System.out.println (CO1.compareto (CO2)); // 0system.out.println (CO1.compareto (CO3)); // -4
Este método se escribe ingeniosamente, y puede juzgar el tamaño del personaje desde 0 primero.
Si la comparación entre los dos objetos puede comparar caracteres sigue siendo igual, entonces la longitud del objeto que se compara se devuelve directamente. Si la longitud de las dos cuerdas es igual, entonces el retorno es 0, que juzga hábilmente las tres situaciones.
3.Code
int hashcode () public int hashcode () {int h = hash; // Si el hash no se ha calculado y la cadena no está vacía, entonces el cálculo de hashcode se realiza si (h == 0 && valor.length> 0) {char val [] = valor; // proceso de cálculo // s [0]*31^(n-1) + s [1]*31^(n-2) + ... + s [n-1] para (int i = 0; i <valor.length; i ++) {h = 31*h + val [i]; } // asignación hash hash = h; } return h;}Cadena a = "toyou"; char val [] = A.toCarArray (); 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 // Cálculo hashcode porque los caracteres de char se pueden convertir automáticamente en la configuración int correspondiente
La clase de cadena anula el método hashcode, y el método hashcode en el objeto es una llamada nativa.
El hash de la clase de cadena se calcula utilizando polinomios. Podemos obtener completamente el mismo hash a través de diferentes cuerdas. Por lo tanto, el húsico de dos objetos de cadena es el mismo, lo que no significa que las dos cadenas sean las mismas.
El húsico del mismo objeto de cadena debe ser el mismo, pero el húsico es el mismo, no necesariamente el mismo objeto
4.
boolean startswith (string prefix, int toffset) public boolean startswith (string prefix, int toffset) {char ta [] = valor; int tT = toffset; char pa [] = prefix.value; int po = 0; int pc = prefix.value.length; // NOTA: Toffset puede estar cerca de -1 >>> 1. // Si la dirección inicial es inferior a 0 o (dirección de inicio + longitud del objeto comparado) es mayor que la longitud del objeto propio, return false if ((toffset <0) || (toffset> value.length - pc)) {return false; } // Compare desde el final del objeto que se compara mientras (--pc> = 0) {if (ta [to ++]! = Pa [po ++]) {return false; }} return true;} public boolean startswith (string prefix) {return startswith (prefix, 0);} public boolean endswith (sufijo de cadena) {return startswith (sufix, value.length - sufix.value.length);}; Cadena d = "www.58fxp.com"; System.out.println (D.Startswith ("www")); // true system.out.println (d.endswith ("com")); // verdaderoComparación de inicio y finalización son métodos comunes. Por ejemplo, al juzgar si una cadena es del protocolo HTTP, o inicialmente juzga si un archivo es un archivo MP3, puede usar este método para comparar.
5. CONCAT
String concat (string str) public string concat (string str) {int otherlen = str.length (); // Si la cadena agregada está vacía, devuelva el objeto en sí mismo si (otro Len == 0) {return esto; } int len = value.length; char buf [] = arrays.copyOf (valor, len + otherlen); str.getChars (buf, len); return new String (buf, true);} Cadena cat = "mucho"; Cadena newCat = cat.concat ("sí"); // mucho siEl método Concat también es uno de los métodos comúnmente utilizados. Primero determina si la cadena agregada está vacía para decidir si crear un nuevo objeto.
1 Si la longitud del personaje empalmado es 0, regrese directamente al objeto de caracteres original
2 Los caracteres empalmados no están vacíos y devuelven un nuevo objeto de caracteres
Determine la longitud del carácter para generar un nuevo objeto
6. Replacos
String reemplazar (char OldChar, char NewChar) Public String Reemplazar (char OldChar, char Newchar) {// Compare los valores antiguos y nuevos primero if (OldChar! = NewChar) {int Len = value.length; int i = -1; char [] val = valor; / * Evite Getfield OpCode */ // Encuentre la posición donde el valor anterior aparece primero mientras (++ i <len) {if (val [i] == OldChar) {break; }} // Desde esa posición, hasta el final, reemplace el valor anterior que aparece con el nuevo valor if (i <len) {char buf [] = new Char [Len]; para (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); }} devuelve esto;} String r1 = "cómo lo haces"; Cadena r2 = r1.replace ("do", "is"); system.out.println (r2); // ¿Cómo estás?Este método también tiene cierta inteligencia, como descubrir dónde aparece el valor anterior al principio, lo que ahorra cierto tiempo de comparación.
El método Reemplazar (String OldStr, String Newstr) se juzga por expresiones regulares.
7. Trim
String TRIM () public String TRIM () {int len = value.length; int st = 0; char [] val = valor; / * Evite Getfield OpCode */ // Encuentre la posición sin espacios frente a la cadena mientras ((st <len) && (val [st] <= '')) {st ++; } // Encuentre la posición sin espacios al final de la cadena mientras ((st <len) && (val [len-1] <= '')) {len--; } // Si no hay espacios al frente y después, devuelva la cadena en sí ((st> 0) || (len <value.length))? subcadena (st, len): this;} Cadena t1 = "public void"; // un espacio en el frente y después del sistema.out.println ("t1:"+t1.length ()); // 13 con cadena de longitud de espacio t2 = t1.trim (); System.out.println ("T2:"+T2.Length ()); // 11 Retire el espacio System.out.println (T2);8.
String Intern () public Native String Intern ();
String dd = new String ("BB"). Intern ();El método nternal es una llamada nativa, y su función es encontrar objetos de igual valor a través del método igual en el grupo constante en el área del método.
Si no se encuentra, abra un espacio en la piscina constante para almacenar la cadena y devolver la referencia a la cadena correspondiente. De lo contrario, devuelva directamente la referencia al objeto de cadena ya existe en el grupo constante.
También puede forzar el objeto de caracteres creado para el nuevo método para ver si el grupo constante ya existe.
Pon el segundo código en la introducción
// String a = new String ("AB1"); // Cambiar a String A = New String ("AB1"). Intern ();El resultado es verdadero, porque la dirección apuntada por A proviene del grupo constante, y la constante de cadena apuntada por B llamará a este método de forma predeterminada, por lo que A y B apuntan al mismo espacio de dirección.
int hash32 () privado transitorio int hash32 = 0; int hash32 () {int h = hash32; if (0 == H) {// RACA DE DATOS INFERMENTES EN Hash32 aquí. h = sun.misc.hashing.murmur3_32 (hashing_seed, valor, 0, valor.length); // ¿Asegúrese de que el resultado no sea cero para evitar recalcular H = (0! = H)? H: 1; hash32 = h; } return h;}En JDK1.7, cuando la clase de cadena se usa como clave, la clase de recolección relacionada con el hash ya no usa el método hashcode para discretos datos, pero usa el método Hash32.
Este método utiliza la dirección actual del sistema, la dirección de clase de cadena, la dirección de clase del sistema, etc. como factores para calcular la semilla hash. A través de la semilla hash, se obtiene un valor INT de 32 bits a través de la semilla hash.
public int long () {return value.length;} public string toString () {return this;} public boolean isEtimty () {return value.length == 0;} public char charat (int index) {if ((index <0) || (index> = value.length)) {tirar nueva StringintexoutOfBoundsexception (index); } valor de retorno [índice];}Los anteriores son algunos métodos comunes simples.
Resumir
Los objetos de cadena son tipos inmutables. Métodos de cadena con Tipo de retorno de retorno cada vez que se devuelve un nuevo objeto de cadena, excepto para ciertas condiciones específicas de algunos métodos para devolver.
Tres formas de comparar objetos de cadena:
== Comparación de memoria: compare directamente los valores de memoria apuntados por las dos referencias, que son precisas, concisas y directas.
Igual de la comparación del valor de la cadena: compare si los valores literales de los dos objetos referenciados son iguales.
Comparación de la numericalización de cadena de hashcode: numericalización de cadenas. Los dos hashcodes referenciados son los mismos, y no se garantiza que la memoria sea la misma, y los valores litentes no se garantizan que son los mismos.
Idea de diseño del grupo constante de cadena
1. Intención original del diseño de la piscina constante
Cada cadena es un objeto de cadena, y las cadenas se utilizarán con frecuencia en el desarrollo del sistema. Si se crea y destruye como otros objetos, afectará en gran medida el rendimiento del programa.
Para mejorar el rendimiento y reducir la sobrecarga de memoria, JVM se optimiza al instanciar cadenas.
Se abre una piscina constante de cadena para cuerdas, similar a un área de caché
Al crear una constante de cadena, primero determine si existe el grupo constante de cadena.
La cadena devuelve una instancia referenciada, no existe, instanciar la cadena y ponerla en el grupo.
Darse cuenta de lo básico
La base para implementar esta optimización es que cada constante de cadena es una constante modificada final, por lo que no hay necesidad de preocuparse por los conflictos de datos en el grupo constante.
Hay una tabla en el grupo constante de cadena global creado por la instancia de tiempo de ejecución, que siempre mantiene una referencia para cada objeto de cadena único en la piscina, lo que significa que siempre se refieren a objetos en la piscina constante de cadena, por lo que el recolector de basura no recolectará estas cuerdas en la piscina constante.
Montón, pila, área de método
Comprensión de las piscinas constantes de cadena, primero mire el área del método de la pila
montón
Lo que se almacena es un objeto, cada objeto contiene una clase correspondiente
El JVM solo tiene un área de montón y es compartido por todos los hilos. No hay tipos básicos y referencias de objetos en el montón, sino solo el objeto en sí
Los objetos son recolectados por el recolector de basura, por lo que no es necesario determinar el tamaño y el ciclo de vida
Pila
Cada hilo contiene un área de pila, que solo almacena objetos de tipo de datos básicos y referencias de objetos personalizados.
Los datos (tipo primitivo y referencia de objeto) en cada pila son privados
La pila se divide en tres partes: el área variable de tipo básica, el contexto del entorno de ejecución y el área de instrucción de operación (instrucciones de operación de almacenamiento)
El tamaño de los datos y el ciclo de vida son ciertos, y cuando no apunta a estos datos, los datos desaparecerán.
Área de método
Las zonas estáticas, como los montones, son compartidas por todos los hilos
El área del método contiene elementos que siempre son únicos en todo el programa, como variables de clase y estática;
Piscina constante
Cadena existe una piscina constante en el área del método
Código: Método de pila Tiendas de área
String str1 = "ABC"; String str2 = "ABC"; String Str3 = "ABC"; String Str4 = New String ("ABC"); String Str5 = New String ("ABC");Preguntas de entrevista
String str4 = new String ("ABC") ¿Cuántos objetos se crean?
Split: str4 =, new String (), "ABC"
Puede crear un nuevo objeto a través del nuevo método. El nuevo método crea un objeto instanciado y no irá al grupo constante para encontrar si ya existe. Mientras sea nuevo, se instanciará un nuevo objeto.
"ABC" Cada cadena es un objeto de cadena. Si no hay en el grupo constante, se creará un nuevo objeto y se colocará en la piscina constante. De lo contrario, se devolverá la referencia del objeto.
Asigne la dirección del objeto a STR4 y cree una referencia
Entonces, si no hay literal "ABC" en el grupo constante, cree dos objetos, de lo contrario crear un objeto y crear una referencia
Cadena str1 = nueva cadena ("A"+"B"); ¿Cuántos objetos se crearán? String str2 = new String ("ABC") + "ABC"; ¿Cuántos objetos se crearán?
El análisis completo anterior del código fuente de cadena Java y el grupo de constantes de cadena es todo el contenido que comparto con usted. Espero que pueda darle una referencia y espero que pueda apoyar más a Wulin.com.