De acuerdo con String # intern () , intern
se supone que el método devuelve el String del conjunto de String si el String se encuentra en el conjunto de String; de lo contrario, se agregará un nuevo objeto de string en el conjunto de String y se devolverá la referencia de este String.
Entonces intenté esto:
String s1 = "Rakesh";
String s2 = "Rakesh";
String s3 = "Rakesh".intern();
if ( s1 == s2 ){
System.out.println("s1 and s2 are same"); // 1.
}
if ( s1 == s3 ){
System.out.println("s1 and s3 are same" ); // 2.
}
Esperaba que s1 and s3 are same
se imprimiera cuando s3 está internado y s1 and s2 are same
no se imprimirá. Pero el resultado es: ambas líneas se imprimen. Eso significa que, por defecto, las constantes de cadena están internadas. Pero si es así, ¿por qué necesitamos el intern
método? En otras palabras, ¿cuándo debemos usar este método?
java
string
string-interning
Rakesh Juyal
fuente
fuente
intern
como método público? ¿No deberíamos tenerintern
un método privado para que nadie pueda tener acceso a él? ¿O hay algún propósito de este método?Respuestas:
Java pasa automáticamente los literales de cadena. Esto significa que en muchos casos, el operador == parece funcionar para las cadenas de la misma manera que lo hace para ints u otros valores primitivos.
Dado que la internación es automática para los literales de cadena, el
intern()
método se debe usar en cadenas construidas connew String()
Usando tu ejemplo:
volverá:
En todos los casos además de la
s4
variable, un valor para el cual se creó explícitamente utilizando elnew
operador y donde elintern
método no se usó en su resultado, es una instancia inmutable única que se devuelve el grupo constante de cadenas de JVM .Consulte JavaTechniques "String Equality and Interning" para obtener más información.
fuente
String s1 = "Rakesh";
primer OB1String s4 = new String("Rakesh");
Segundo OB2 Entonces, el resto de (s2, s3, s5) hace referencia al mismo objeto (OB1) creado en el 'Conjunto de cadenas'. Entonces, ¿puedo decir que el.intern()
método utilizado para evitar crear un nuevo objeto si la misma cadena está disponible enstring pool
If mi suposición es incorrecta, así que dame dirección.En un proyecto reciente, se configuraron algunas estructuras de datos enormes con datos que se leyeron desde una base de datos (y, por lo tanto, no constantes / literales de cadena) pero con una gran cantidad de duplicación. Era una aplicación bancaria, y cosas como los nombres de un conjunto modesto (quizás 100 o 200) corporaciones aparecieron por todas partes. Las estructuras de datos ya eran grandes, y si todos esos nombres de cuerpos hubieran sido objetos únicos, habrían desbordado la memoria. En cambio, todas las estructuras de datos tenían referencias a los mismos 100 o 200 objetos String, ahorrando así mucho espacio.
Otra pequeña ventaja de las cadenas internas es que
==
se puede usar (¡con éxito!) Para comparar cadenas si se garantiza que todas las cadenas involucradas serán internadas. Además de la sintaxis más ágil, esta también es una mejora de rendimiento. Pero como otros han señalado, hacer esto alberga un gran riesgo de introducir errores de programación, por lo que esto debe hacerse solo como una medida desesperada de último recurso.La desventaja es que internar un String lleva más tiempo que simplemente lanzarlo al montón y que el espacio para los Strings internados puede ser limitado, dependiendo de la implementación de Java. Es mejor hacerlo cuando se trata de un número razonable conocido de cadenas con muchas duplicaciones.
fuente
The downside is that interning a String takes more time than simply throwing it on the heap, and that the space for interned Strings may be limited
incluso si no utiliza el método interno para la constante de cadena, se internará automáticamente.==
embargo, no estoy de acuerdo con las cadenas.Quiero agregar mis 2 centavos al usar
==
con cadenas internas.Lo primero que
String.equals
hace esthis==object
.Entonces, aunque hay una ganancia de rendimiento minúscula (no está llamando a un método), desde el punto de vista del mantenedor, el uso
==
es una pesadilla, porque algunas cadenas internas tienen una tendencia a no ser internadas.Por lo tanto, sugiero no confiar en un caso especial de
==
cadenas internados, sino utilizar siempreequals
como Gosling pretendía.EDITAR: internado convirtiéndose en no interno:
En la versión 2.0, el mantenedor decidió hacer
hasReferenceVal
público, sin entrar en muchos detalles, que espera una serie de cadenas internados.Ahora tiene un error, que puede ser muy difícil de encontrar, porque en la mayoría de los casos la matriz contiene valores literales y, a veces, se usa una cadena no literal. Si
equals
se usara en lugar de==
entonceshasReferenceVal
, todavía habría seguido funcionando. Una vez más, el aumento de rendimiento es minúsculo, pero el costo de mantenimiento es alto.fuente
Los literales de cadena y las constantes se internan por defecto. Es decir,
"foo" == "foo"
(declarado por los literales de cadena), peronew String("foo") != new String("foo")
.fuente
intern
,String literals and constants are interned by default
es correcta.new String("foo")
-> Aquí, se crea un Stro literal "foo" en el conjunto de String y uno en el montón, por lo que se crean un total de 2 objetos.Aprenda Java String Intern - de una vez por todas
Las cadenas en Java son objetos inmutables por diseño. Por lo tanto, dos objetos de cadena incluso con el mismo valor serán objetos diferentes por defecto. Sin embargo, si deseamos ahorrar memoria, podríamos indicar que usemos la misma memoria mediante un concepto llamado string intern.
Las siguientes reglas lo ayudarán a comprender el concepto en términos claros:
Ejemplo:
Nota: Los casos motivacionales para el pasante interno no se discuten aquí. Sin embargo, el ahorro de memoria definitivamente será uno de los objetivos principales.
fuente
debe distinguir el tiempo de dos períodos, que son el tiempo de compilación y el tiempo de ejecución, por ejemplo:
por un lado, en el ejemplo 1, encontramos que todos los resultados son verdaderos, porque en el tiempo de compilación, jvm pondrá la "prueba" en el conjunto de cadenas literales, si existe la "prueba" de jvm find, entonces utilizará el existente, en el ejemplo 1, las cadenas de "prueba" apuntan a la misma dirección de memoria, por lo que el ejemplo 1 devolverá verdadero. por otro lado, en el ejemplo 2, el método de substring () se ejecuta en el tiempo de ejecución, en el caso de "test" == "! test" .substring (1), el grupo creará dos objetos de cadena " test "y"! test ", por lo que son diferentes objetos de referencia, por lo que este caso devolverá falso, en el caso de" test "=="! test ".substring (1) .intern (), el método de interno ( ) colocará ""! test ".substring (1)" en el conjunto de cadenas literales,
fuente
http://en.wikipedia.org/wiki/String_interning
El internamiento de cadenas es un método para almacenar solo una copia de cada valor de cadena distinto, que debe ser inmutable. Internar cadenas hace que algunas tareas de procesamiento de cadenas sean más eficientes en tiempo o espacio a costa de requerir más tiempo cuando la cadena se crea o se interna. Los valores distintos se almacenan en un grupo interno de cadenas.
fuente
Las cadenas internas evitan cadenas duplicadas. Interning ahorra RAM a expensas de más tiempo de CPU para detectar y reemplazar cadenas duplicadas. Solo hay una copia de cada Cadena que ha sido internada, sin importar cuántas referencias la señalen. Como las cadenas son inmutables, si dos métodos diferentes usan la misma cadena, pueden compartir una copia de la misma cadena. El proceso de convertir cadenas duplicadas en cadenas compartidas se llama interning.String.intern () le proporciona la dirección de la cadena maestra canónica. Puede comparar cadenas internas con simple == (que compara punteros) en lugar de igualesque compara los caracteres de la cadena uno por uno. Debido a que las cadenas son inmutables, el proceso interno es libre de ahorrar más espacio, por ejemplo, al no crear un literal de cadena separado para "pot" cuando existe como una subcadena de algún otro literal como "hipopótamo".
Para ver más http://mindprod.com/jgloss/interned.html
fuente
SALIDA
fuente
Cuando se crean dos cadenas de forma independiente, le
intern()
permite compararlas y también le ayuda a crear una referencia en el grupo de cadenas si la referencia no existía antes.Cuando lo usa
String s = new String(hi)
, java crea una nueva instancia de la cadena, pero cuando lo usaString s = "hi"
, java verifica si hay una instancia de la palabra "hola" en el código o no, y si existe, simplemente devuelve la referencia.Dado que la comparación de cadenas se basa en la referencia, le
intern()
ayuda a crear una referencia y le permite comparar el contenido de las cadenas.Cuando lo usa
intern()
en el código, borra el espacio utilizado por la cadena que se refiere al mismo objeto y solo devuelve la referencia del mismo objeto ya existente en la memoria.Pero en el caso de p5 cuando está usando:
Solo se copia el contenido de p3 y se crea p5 nuevamente. Entonces no está internado .
Entonces la salida será:
fuente
fuente
El método string intern () se usa para crear una copia exacta del objeto de cadena de montón en el grupo de cadenas constantes. Los objetos de cadena en el grupo de constantes de cadena se internan automáticamente, pero los objetos de cadena en el montón no. El uso principal de crear pasantes es ahorrar espacio en la memoria y realizar una comparación más rápida de los objetos de cadena.
Fuente: ¿Qué es string intern en java?
fuente
Como dijiste, ese
intern()
método de cadena primero se encontrará en el grupo de cadenas, si lo encuentra, devolverá el objeto que apunta a eso o agregará una nueva cadena al grupo.El
s1
ys2
son dos objetos que apuntan al conjunto de cadenas "Hola", y el uso"Hello".intern()
encontrará ques1
ys2
. Entonces"s1 == s3"
vuelve verdadero, así como a las3.intern()
.fuente
Al usar la referencia de objeto de montón si queremos obtener la referencia de objeto de agrupación constante de cadena correspondiente , entonces deberíamos elegir intern ()
Vista pictórica
Paso 1: El objeto con datos 'Rakesh' se crea en el grupo constante de montón y cadena. También s1 siempre apunta al objeto de montón.
Paso 2: Al usar la referencia de objeto de montón s1, estamos tratando de obtener la referencia de objeto de agrupación constante de cadena correspondiente s2, usando intern ()
Paso 3: Crear intencionalmente un objeto con datos 'Rakesh' en el grupo constante de cadenas, referenciado por el nombre s3
Como operador "==" destinado a la comparación de referencia.
Obteniendo falso para s1 == s2
Obteniéndose verdadero para s2 == s3
¡¡Espero que esto ayude!!
fuente