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 CharSequenceexcesivo 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
CharSequencejavadoc: esta interfaz no refina los contratos generales de los métodosequalsyhashCode. El resultado de comparar dos objetos que implementanCharSequencees, 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 usarCharSequenceinstancias arbitrarias como elementos en un conjunto o como claves en un mapa.CharSequencefue 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.equalscomo "contiene la misma secuencia de caracteres". NIOCharBuffer, por ejemplo, solo expone los caracteres entre supositionylimitcomo elCharSequence, a pesar de tener potencialmente muchos otros caracteres.equals/hashCodeenObjecten el primer lugar ....ObjectoCharSequence, no se requiere ninguna interfaz para proporcionar la cordura igualdad entre implementaciones. NoCollectionse requieren dos s para proporcionar igualdad entre laCollectioninterfaz, pero pueden hacerlo si así lo desean. En mi humilde opinión,CharSequencedebe limitarse a las entradas y utilizar menos para tipos de retorno.CharSequence= interfazString= implementación concretaCharSequencees una interfaz .Stringes una de esas clases, una implementación concreta deCharSequence.Tu dijiste:
No hay conversión de
String.Stringobjeto es unCharSequence.CharSequencepueden producir aString. LlamadaCharSequence::toString. Si elCharSequencepasa a ser unString, entonces el método devuelve una referencia a su propio objeto.En otras palabras, cada
Stringes unCharSequence, pero no todosCharSequenceson 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
Listen lugar deArrayList,LinkedListo 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.
Stringsabes 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
CharSequenceobjeto 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
Stringes aCharSequence. Si su método declara que toma unCharSequence, el programador que llama puede pasar unStringobjeto, o puede pasar algo más como unStringBufferoStringBuilder. El código de su método simplemente usará lo que se haya pasado, llamando a cualquiera de losCharSequencemétodos.Lo más cerca que estaría de convertir es si su código recibe un
CharSequencey sabe que necesita unString. Quizás esté interactuando con el código antiguo escrito en laStringclase en lugar de hacerlo en laCharSequenceinterfaz. 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 llamartoStringpor 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
CharSequenceinterfaz 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 idealCharSequenceserí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
CharSequenceimplementación para eso.CharSequencees una interfaz : por definición, no tiene ninguno de los detalles de implementación que discute porque no tiene implementación propia. AStringes una de varias clases concretas que implementa laCharSequenceinterfaz. Entonces aStringes aCharSequence. Puede comparar los detalles de rendimiento deStringvsStringBuffervsStringBuilder, 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
CharSequencees 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, aCharSequencees 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
CharSequenceobjeto, entonces en realidad es un objeto de una de las clases que implementaCharSequence. Por ejemplo:El beneficio de tener un tipo general de paraguas
CharSequencees que puede manejar múltiples tipos con un solo método. Por ejemplo, si tengo un método que toma aCharSequencecomo parámetro, podría pasar aStringo aSpannableStringBuildery manejaría cualquiera de ellos.Cuerda
Se podría decir que a
Stringes 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
CharSequencees solo una lista de reglas que seStringajustan, 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
Stringparámetro, no puede pasarle algo que generalmente se conoce como aCharSequence, porque en realidad podría ser unSpannableStringu otro tipo deCharSequence.fuente
CharSequencees una interfaz y laStringimplementa. Puede crear una instancia deStringpero no puede hacerloCharSequenceporque es una interfaz. Puede encontrar otras implementacionesCharSequenceen 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
CharSequenceno implementaString. Sin embargo, lo contrario es cierto.