CharSequence VS String en Java?

Progtwigndo en Android, la mayoría de los valores de texto se esperan en CharSequence .

¿Porqué es eso? ¿Cuál es el beneficio y cuáles son los principales impactos del uso de CharSequence sobre String?

¿Cuáles son las principales diferencias y qué problemas se esperan al utilizarlos y al convertirlos de uno a otro?

Las cadenas son CharSequences , por lo que solo puedes usar cadenas y no preocuparte. Android simplemente está tratando de ser útil al permitirle también especificar otros objetos CharSequence, como StringBuffers.

Este diagtwig de clases puede ayudarlo a ver el outlook 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 puede serle útil.

Además, tenga en cuenta los comentarios realizados sobre la Respuesta aceptada . La interfaz CharSequence se CharSequence a estructuras de clases existentes, por lo que hay algunas sutilezas importantes ( equals() y 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 CharSequence sería que CharSequence hubiera estado en su lugar desde el principio, pero tal es la vida.

diagrama de varias clases e interfaces relacionadas con cadenas

Creo que es mejor usar CharSequence. La razón es que String implementa CharSequence, por lo tanto, puede pasar una Cadena a una CharSequence, SIN EMBARGO no puede pasar una CharSequence a una Cadena, ya que CharSequence no implementa Cadena. TAMBIÉN, en Android el método EditText.getText() devuelve un Editable, que también implementa CharSequence y se puede pasar fácilmente a uno, aunque no fácilmente en un String. ¡CharSequence maneja todo!

En general, usar una interfaz le permite variar la implementación con un mínimo daño colateral. Aunque java.lang.String es muy popular, es posible que en ciertos contextos, uno quiera usar otra implementación. Al construir la API alrededor de CharSequences en lugar de cadenas, el código da la oportunidad de hacerlo.

Esto es casi seguro razones de rendimiento. Por ejemplo, imagina un analizador sintáctico que atraviesa un byteBuffer de 500k que contiene cadenas.

Hay 3 enfoques para devolver el contenido de la cadena:

  1. Construye una Cadena [] en el 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é.

  2. Construya un int [] con desplazamientos en el tiempo de análisis, luego construya de forma dinámica String cuando ocurra un get (). Cada cadena será un objeto nuevo, por lo que ningún almacenamiento en caché devolvió valores y usar ==

  3. Construye una CharSequence [] en el tiempo de análisis. Como no se almacenan datos nuevos (que no sean desplazamientos en el búfer de bytes), el análisis es mucho menor que el # 1. Al llegar el momento, no necesitamos construir un String, así que el rendimiento es igual a # 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 al utilizar 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 3 o un solo párrafo, necesita 4 cadenas para representar esto. Usando CharSequence solo necesitas 1 buffer con los datos, y 4 instancias de una implementación de CharSequence que rastrea el inicio y la duración.

Un problema que surge en el código práctico de Android es que compararlos con CharSequence.equals es válido, pero no necesariamente funciona como se esperaba.

 EditText t = (EditText )getView(R.id.myEditText); // Contains "OK" Boolean isFalse = t.getText().equals("OK"); // will always return false. 

La comparación debe hacerse por

 ("OK").contentEquals(t.GetText()); 

CharSequence

Una 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, una CharSequence es un paraguas para varios tipos de cadenas de texto. Estos son algunos de los más comunes:

  • String (texto inmutable sin tramos de estilo)
  • StringBuilder (texto mutable sin tramos de estilo)
  • SpannableString (texto inmutable con tramos de estilo)
  • SpannableStringBuilder (texto mutable con tramos de estilo)

(Puede leer más sobre las diferencias entre estos aquí ).

Si tiene un objeto CharSequence , entonces en realidad es un objeto de una de las clases que implementa CharSequence . Por ejemplo:

 CharSequence myString = "hello"; CharSequence mySpannableStringBuilder = new SpannableStringBuilder(); 

El beneficio de tener un tipo paraguas general como CharSequence es que puedes manejar múltiples tipos con un solo método. Por ejemplo, si tengo un método que toma una CharSequence como parámetro, podría pasar un String o un SpannableStringBuilder y manejaría cualquiera de ellos.

 public int getLength(CharSequence text) { return text.length(); } 

Cuerda

Se podría decir que una String es solo un tipo de CharSequence de CharSequence . Sin embargo, a diferencia de CharSequence , es una clase real, por lo que puede crear objetos a partir de ella. Entonces podrías hacer esto:

 String myString = new String(); 

pero no puedes hacer esto:

 CharSequence myCharSequence = new CharSequence(); // error: 'CharSequence is abstract; cannot be instantiated 

Como CharSequence es solo una lista de reglas a las que se CharSequence String , puedes hacer esto:

 CharSequence myString = new String(); 

Eso significa que cada vez que un método solicite una CharSequence , está bien darle una String .

 String myString = "hello"; getLength(myString); // OK // ... public int getLength(CharSequence text) { return text.length(); } 

Sin embargo, lo opuesto no es verdad. Si el método toma un parámetro String , no puede pasarle algo que generalmente solo se conoce como CharSequence , porque podría ser realmente SpannableString o algún otro tipo de CharSequence .

 CharSequence myString = "hello"; getLength(myString); // error // ... public int getLength(String text) { return text.length(); } 

CharSequence es una interfaz y String implementa. Puedes instanciar una String pero no podrías hacer eso para CharSequence ya que es una interfaz. Puede encontrar otras implementaciones en CharSequence en el sitio web oficial de Java.

CharSequence es una secuencia legible de valores de char que implementa String. tiene 4 métodos

  1. charAt (índice int)
  2. longitud()
  3. subSecuencia (int start, int end)
  4. Encadenar()

Consulte la documentación documentación de CharSequence

    Intereting Posts