Programando en Android, se esperan la mayoría de los valores de texto CharSequence
.
¿Porqué es eso? ¿Cuál es el beneficio y cuáles son los principales impactos del uso CharSequence
excesivo String
?
¿Cuáles son las principales diferencias y qué problemas se esperan al usarlos y convertirlos de uno a otro?
java
string
charsequence
e-satis
fuente
fuente
Respuestas:
Las cadenas son secuencias de caracteres , por lo que puede usar cadenas y no preocuparse. Android simplemente está tratando de ser útil permitiéndole especificar también otros objetos CharSequence, como StringBuffers.
fuente
CharSequence
javadoc: esta interfaz no refina los contratos generales de los métodosequals
yhashCode
. El resultado de comparar dos objetos que implementanCharSequence
es, por lo tanto, en general, indefinido . Cada objeto puede ser implementado por una clase diferente, y no hay garantía de que cada clase sea capaz de probar la igualdad de sus instancias con las de la otra. Por lo tanto, es inapropiado usarCharSequence
instancias arbitrarias como elementos en un conjunto o como claves en un mapa.CharSequence
fue una modificación en JDK 1.4 para introducir una interfaz común de propósito limitado a los objetos que contienen secuencias de caracteres. Algunos de esos objetos contienen otro estado, por lo que puede no tener sentido definirObject.equals
como "contiene la misma secuencia de caracteres". NIOCharBuffer
, por ejemplo, solo expone los caracteres entre suposition
ylimit
como elCharSequence
, a pesar de tener potencialmente muchos otros caracteres.equals
/hashCode
enObject
en el primer lugar ....Object
oCharSequence
, no se requiere ninguna interfaz para proporcionar la cordura igualdad entre implementaciones. NoCollection
se requieren dos s para proporcionar igualdad entre laCollection
interfaz, pero pueden hacerlo si así lo desean. En mi humilde opinión,CharSequence
debe limitarse a las entradas y utilizar menos para tipos de retorno.CharSequence
= interfazString
= implementación concretaCharSequence
es una interfaz .String
es una de esas clases, una implementación concreta deCharSequence
.Tu dijiste:
No hay conversión de
String
.String
objeto es unCharSequence
.CharSequence
pueden producir aString
. LlamadaCharSequence::toString
. Si elCharSequence
pasa a ser unString
, entonces el método devuelve una referencia a su propio objeto.En otras palabras, cada
String
es unCharSequence
, pero no todosCharSequence
son unString
.Programando a una interfaz
En general, programar en una interfaz es mejor que programar en clases concretas. Esto proporciona flexibilidad, por lo que podemos cambiar entre implementaciones concretas de una interfaz particular sin romper otro código.
Al desarrollar una API para ser utilizada por varios programadores en diversas situaciones, escriba su código para dar y tomar las interfaces más generales posibles. Esto le da al programador que llama la libertad de usar diversas implementaciones de esa interfaz, la implementación que sea mejor para su contexto particular.
Por ejemplo, mire el Java Collections Framework . Si su API da o toma una colección ordenada de objetos, declarar sus métodos como el uso
List
en lugar deArrayList
,LinkedList
o cualquier otra aplicación de 3 ª parteList
.Al escribir un pequeño método rápido y sucio para ser usado solo por su código en un lugar específico, en lugar de escribir una API para usar en varios lugares, no necesita molestarse en usar la interfaz más general en lugar de un concreto específico clase. Pero incluso entonces, le duele usar la interfaz más general que pueda.
String
sabes que tienes una sola pieza de texto, completamente en memoria, y es inmutable.CharSequence
, no sabe cuáles podrían ser las características particulares de la implementación concreta.El
CharSequence
objeto puede representar una enorme porción de texto y, por lo tanto, tiene implicaciones de memoria. O puede haber muchos fragmentos de texto rastreados por separado que necesitarán unirse cuando llametoString
, y por lo tanto tiene problemas de rendimiento. La implementación puede incluso recuperar texto de un servicio remoto y, por lo tanto, tiene implicaciones de latencia.Por lo general, no se convertirá de un lado a otro. A
String
es aCharSequence
. Si su método declara que toma unCharSequence
, el programador que llama puede pasar unString
objeto, o puede pasar algo más como unStringBuffer
oStringBuilder
. El código de su método simplemente usará lo que se haya pasado, llamando a cualquiera de losCharSequence
métodos.Lo más cerca que estaría de convertir es si su código recibe un
CharSequence
y sabe que necesita unString
. Quizás esté interactuando con el código antiguo escrito en laString
clase en lugar de hacerlo en laCharSequence
interfaz. O tal vez su código trabajará intensamente con el texto, como hacer bucles repetidamente o analizar de otro modo. En ese caso, desea recibir cualquier posible golpe de rendimiento solo una vez, por lo que debe llamartoString
por adelantado. Luego, continúe con su trabajo utilizando lo que sabe que es una sola pieza de texto completamente en la memoria.Historia retorcida
Tenga en cuenta los comentarios realizados en la respuesta aceptada . La
CharSequence
interfaz se actualizó en las estructuras de clase existentes, por lo que hay algunas sutilezas importantes (equals()
&hashCode()
). Observe las diversas versiones de Java (1, 2, 4 y 5) etiquetadas en las clases / interfaces, un poco de abandono a lo largo de los años. Lo idealCharSequence
sería haber estado en su lugar desde el principio, pero así es la vida.Mi diagrama de clases a continuación puede ayudarlo a ver el panorama general de los tipos de cadenas en Java 7/8. No estoy seguro de si todos estos están presentes en Android, pero el contexto general aún puede resultarle útil.
fuente
Creo que es mejor usar CharSequence. La razón es que String implementa CharSequence, por lo tanto, puede pasar un String a un CharSequence, SIN EMBARGO, no puede pasar un CharSequence a un String, ya que CharSequence no implementa el String. TAMBIÉN, en Android, el
EditText.getText()
método devuelve un Editable, que también implementa CharSequence y se puede pasar fácilmente a uno, aunque no fácilmente a una Cadena. ¡CharSequence se encarga de todo!fuente
charSequence.toString()
En general, el uso de una interfaz le permite variar la implementación con un daño colateral mínimo. Aunque java.lang.String son súper populares, es posible que en ciertos contextos uno quiera usar otra implementación. Al construir la API alrededor de CharSequences en lugar de Strings, el código le da a uno la oportunidad de hacerlo.
fuente
Esto es casi seguro razones de rendimiento. Por ejemplo, imagine un analizador que pasa por un ByteBuffer de 500k que contiene cadenas.
Hay 3 enfoques para devolver el contenido de la cadena:
Cree una Cadena [] en tiempo de análisis, un carácter a la vez. Esto llevará una cantidad de tiempo notable. Podemos usar == en lugar de .equals para comparar referencias en caché.
Construya un int [] con desplazamientos en tiempo de análisis, luego construya String dinámicamente cuando ocurra un get (). Cada cadena será un objeto nuevo, por lo que no se almacenarán en caché los valores devueltos y se utilizará ==
Cree una secuencia de caracteres [] en tiempo de análisis. Como no se almacenan datos nuevos (aparte de las compensaciones en el búfer de bytes), el análisis es mucho menor que el n. ° 1. En el momento oportuno, no necesitamos construir una Cadena, por lo que obtener un rendimiento es igual al # 1 (mucho mejor que el # 2), ya que solo estamos devolviendo una referencia a un objeto existente.
Además de las ganancias de procesamiento que obtiene usando CharSequence, también reduce la huella de memoria al no duplicar datos. Por ejemplo, si tiene un búfer que contiene 3 párrafos de texto y desea devolver los 3 o un solo párrafo, necesita 4 cadenas para representar esto. Usando CharSequence solo necesita 1 búfer con los datos y 4 instancias de una implementación de CharSequence que rastrea el inicio y la duración.
fuente
CharSequence
implementación para eso.CharSequence
es una interfaz : por definición, no tiene ninguno de los detalles de implementación que discute porque no tiene implementación propia. AString
es una de varias clases concretas que implementa laCharSequence
interfaz. Entonces aString
es aCharSequence
. Puede comparar los detalles de rendimiento deString
vsStringBuffer
vsStringBuilder
, pero noCharSequence
. Escribir "ganancias de procesamiento que obtienes usando CharSequence" no tiene sentido.Un problema que SÍ surge en el código práctico de Android es que compararlos con CharSequence.equals es válido pero no necesariamente funciona según lo previsto.
La comparación debe hacerse por
fuente
CharSequence
A
CharSequence
es una interfaz, no una clase real. Una interfaz es solo un conjunto de reglas (métodos) que una clase debe contener si implementa la interfaz. En Android, aCharSequence
es un paraguas para varios tipos de cadenas de texto. Estos son algunos de los más comunes:String
(texto inmutable sin trazos de estilo)StringBuilder
(texto mutable sin trazos de estilo)SpannableString
(texto inmutable con tramos de estilo)SpannableStringBuilder
(texto mutable con trazos de estilo)(Puede leer más sobre las diferencias entre estos aquí ).
Si tiene un
CharSequence
objeto, entonces en realidad es un objeto de una de las clases que implementaCharSequence
. Por ejemplo:El beneficio de tener un tipo general de paraguas
CharSequence
es que puede manejar múltiples tipos con un solo método. Por ejemplo, si tengo un método que toma aCharSequence
como parámetro, podría pasar aString
o aSpannableStringBuilder
y manejaría cualquiera de ellos.Cuerda
Se podría decir que a
String
es solo un tipo deCharSequence
. Sin embargo, a diferencia deCharSequence
, es una clase real, por lo que puede hacer objetos a partir de ella. Entonces podrías hacer esto:pero no puedes hacer esto:
Dado que
CharSequence
es solo una lista de reglas que seString
ajustan, puede hacer esto:Eso significa que cada vez que un método solicita un
CharSequence
, está bien darle unString
.Sin embargo, lo contrario no es cierto. Si el método toma un
String
parámetro, no puede pasarle algo que generalmente se conoce como aCharSequence
, porque en realidad podría ser unSpannableString
u otro tipo deCharSequence
.fuente
CharSequence
es una interfaz y laString
implementa. Puede crear una instancia deString
pero no puede hacerloCharSequence
porque es una interfaz. Puede encontrar otras implementacionesCharSequence
en el sitio web oficial de Java.fuente
CharSequence es una secuencia legible de valores char que implementa String. tiene 4 métodos
Consulte la documentación Documentación de CharSequence
fuente
CharSequence
no implementaString
. Sin embargo, lo contrario es cierto.