Una pregunta de entrevista de Huawei, por favor ayúdenme
En primer lugar, critique la respuesta que es arrogante
El compilador = para String en Java convertirá automáticamente String en StringBuffer
"Java Programming Thoughts 2nd Edition " Apéndice A: Transferencia y devolución de objetos
Versión china página 759
Versión en inglés página 1054
Las secciones sobrecargadas " " y StringBuffer dicen
Los objetos de la clase String están diseñados para ser constantes y utilizar la técnica de clase complementaria presentada anteriormente. Si observa la clase String en la documentación JDK
(esto se resumirá más adelante), encontrará que cada método en la clase está diseñado para modificar String, de hecho, un lote de nuevos objetos String lo son. generado y devuelto. La cadena original no se ve afectada.
Const de C proporciona constancia de objetos soportada por el compilador; Java no tiene tal característica. Para obtener un objeto persistente
tienes que hacerlo tú mismo, como String.
Dado que el objeto String es constante, puedes tener varios alias para un String. Debido a que es de solo lectura, cualquier
referencia no puede modificar el objeto y no afectará a otras referencias. Por lo tanto, los objetos de solo lectura resuelven bien el problema de los alias.
Esto parece resolver todos los problemas. Siempre que necesites modificar un objeto, crea un montón de nuevas versiones modificadas del objeto, como
String. Sin embargo, para algunas operaciones esto resulta demasiado ineficiente. El operador sobrecargado de cadena ' ' es un ejemplo importante. La sobrecarga significa que " " recibe un significado adicional para una clase específica. (Los ' ' y ' =' sobrecargados para String son los únicos operadores sobrecargados en Java, y Java no permite a los programadores sobrecargar otros operadores).
Utilice el objeto String, ' ' se utiliza para concatenar objetos String :
String s = "abc" foo "def" Integer.toString(47);
Puedes imaginar cómo funciona. La cadena "abc" puede tener un método append(), que genera un nuevo objeto String que concatena "abc" y foo. Después de conectar la nueva cadena a "def", se genera otra nueva cadena,
y así sucesivamente.
C permite a los programadores sobrecargar operadores de forma arbitraria. Debido a que este suele ser un proceso complejo, los diseñadores de Java lo consideran una característica "mala" que no debería incluirse en Java. Realmente no es tan malo, irónicamente, usar la sobrecarga de operadores es mucho más fácil en Java que en C.
Esto ciertamente funciona, pero requiere muchos objetos String intermedios para generar el nuevo String final, y esos resultados intermedios
deben ser recolectados como basura. Sospecho que los diseñadores de Java hicieron esto en primer lugar (es una lección de diseño de software que no se puede saber todo hasta que el código esté escrito y funcionando). Supongo que encontraron que este enfoque era insoportablemente ineficiente.
La solución es una clase complementaria mutable, similar al ejemplo demostrado anteriormente.
La clase complementaria de String se llama StringBuffer, que el compilador crea automáticamente cuando
calcula ciertas expresiones, especialmente cuando el objeto String usa los sobrecargados ' ' y ' ='
StringBuffer . El siguiente ejemplo muestra lo que está sucediendo:
//: apéndice: ImmutableStrings.java
// Demostrando StringBuffer
import com.bruceeckel.simpletest *.
clase pública ImmutableStrings {
monitor de prueba estático privado = nueva prueba()
principal vacío estático público (String[] args) {
p>
String foo = "foo";
String s = "abc" foo "def" Integer.toString(47); .println(s );
// El "equivalente" usando StringBuffer:
StringBuffer sb =
new StringBuffer("abc"); Cadena!
p>sb.append(foo);
sb.append("def"); // Crea cadena! Integer.toString(47) );
System.out.println(sb);
monitor.expect(new String[] {
"abcfoodef47" ,
"abcfoodef47"
}
}
} ///:~
En En el proceso de generar String s, el compilador usa sb para realizar código que es aproximadamente equivalente al siguiente trabajo: crear un StringBuffer y usar append() para agregar nuevas cadenas directamente a este objeto StringBuffer (en lugar de cada
<). p>hacer una nueva copia). Aunque este método es más eficiente, no funciona para cadenas entre comillas, como "abc"y "def", y el compilador las convertirá en objetos String.
Entonces, aunque StringBuffer proporciona
mejor eficiencia, aún puede producir más objetos de los esperados.
Clases String y StringBuffer
Los métodos disponibles para String y StringBuffer se resumen a continuación para que puedas tener una idea de cómo interactuar con ellos. No todos los métodos están incluidos en la tabla
solo se incluyen los métodos importantes relevantes para esta discusión. Los métodos sobrecargados se colocan en una columna separada.
La primera es la clase String:
Parámetros de método, propósito sobrecargado.
Constructor sobrecargado: predeterminado, parámetros vacíos, crea objetos String.
Cadena, StringBuffer,
matriz de caracteres, matriz de bytes
longitud () El número de caracteres de la cadena.
charAt( ) int index El carácter
en la posición especificada en la cadena.
getChars (), copia el punto inicial y final de la fuente, copia caracteres o bytes a la matriz de destino externa y la matriz de la matriz de destino.
Índice.
toCharArray() genera un char[] que contiene todos los caracteres de String
.
equals(), prueba la igualdad de dos Strings comparándolos.
es igual a IgnoreCase()
compareTo( ) compara cadenas según el orden del diccionario
y los parámetros, el resultado es un valor negativo, cero,
p>
o un valor positivo. Hay una diferencia entre mayúsculas y minúsculas.
indexOf(), sobrecargado: char, char y si el String actual no contiene
lastIndexOf() índice inicial, String, parámetros de String, devuelve -1, en caso contrario devuelve parámetros
e índice inicial. El índice de posición del número en String.
LastIndexOf() busca en dirección inversa
desde el final.
sobrecargas de subcadena ( ): índice inicial, índice inicial Devuelve un nuevo objeto Cadena que contiene
y un índice final que contiene el conjunto de caracteres especificado.
concat() La cadena que se va a concatenar devuelve un nuevo objeto String con los caracteres del parámetro añadidos a la cadena
original.
replace() busca el carácter antiguo y lo usa para reemplazarlo. Devuelve el nuevo carácter después de que se haya reemplazado el carácter especificado.
El nuevo carácter String objeto. Si no se produce ninguna sustitución
, se devuelve la cadena original.
Generar una y sólo una referencia de Cadena
.
Como puede ver, cuando se debe modificar el contenido de la cadena, cada método de String devolverá cuidadosamente un nuevo objeto String
. También tenga en cuenta que si no es necesario modificar el contenido, el método devuelve una referencia a la cadena de origen. Esto ahorra espacio de almacenamiento y gastos generales.
La siguiente es la clase StringBuffer:
Parámetros del método, propósito de la sobrecarga
Sobrecarga del constructor: parámetros vacíos, buffer que se creará para crear un nuevo StringBuffer
p>p>
Longitud, origen del objeto String.
toString() genera una
cadena a partir de este StringBuffer.
length() El número de caracteres
en StringBuffer.
setLength() es un número entero que representa la longitud de la cadena en el búfer Truncar o extender la cadena original.
Si está expandido, rellene el nuevo espacio
con valores nulos.
charAt() Un número entero que representa la posición deseada del elemento. Devuelve la posición
del carácter en el búfer.
setCharAt( ) representa un número entero en la posición del elemento deseado y new Modifica el valor en una determinada posición.
El valor char de
getChars() copia el punto inicial y final del origen y el destino de la copia char a la matriz periférica. No hay índice de la matriz final ni de la matriz de destino de
. Hay
getBytes() en String.
sobrecarga de append(): el objeto, la cadena y los parámetros se convierten en cadenas y luego se agregan
char[], char[] y la suma de desplazamiento al final del búfer actual. si
grado, booleano, char, int, es necesario, el búfer se expandirá.
long, float, double.
insert() se ha sobrecargado. El primer parámetro se inserta y el segundo parámetro se convierte en una cadena. Valor de desplazamiento del punto inicial: Objeto, en la posición especificada del búfer actual
Cadena, char[], booleano, set. El búfer se expande a char, int, long, float, si es necesario.
double.
El método más utilizado es append(). Al evaluar una expresión de cadena que contiene los operadores ' ' y ' = ', el compilador
String es especial
Hasta ahora, has visto que la clase String es diferente de las clases normales en Java. String tiene muchas características especiales.
No es sólo una clase integrada en Java, se ha convertido en la base de Java. Y, de hecho, el compilador convierte las cadenas entre comillas dobles en objetos String, y hay operadores ' ' y ' = ' especialmente sobrecargados.
En este apéndice,
también puede ver otras especialidades: constancia cuidadosamente construida usando la clase complementaria StringBuffer y
algo de magia adicional en la función del compilador.
/************
La eficiencia de la operación de objetos es baja
Además, todos los objetos Java están en el montón
p>
Texto original Operaciones repetidas sobre objetos
Comportamiento puramente estúpido
************/
// ************************************************* ***** ****
cadena estática pública countStr(int count)
{
char ch [ ] = new char[count];
for(int i = 0; i lt; count; i)
ch [i] = 'A';
String str = new String( ch);
p>
return str;
}
// *************** ********** **********************************