462 Stimmen

CharSequence VS String in Java?

Bei der Programmierung in Android werden die meisten Textwerte in CharSequence .

Warum ist das so? Was ist der Nutzen und was sind die Hauptauswirkungen der Verwendung CharSequence über String ?

Welches sind die Hauptunterschiede und welche Probleme sind bei der Verwendung und der Umstellung von einem zum anderen zu erwarten?

1 Stimmen

8voto

Suragch Punkte 420096

CharSequence

A CharSequence ist eine Schnittstelle, keine echte Klasse. Eine Schnittstelle ist nur ein Satz von Regeln (Methoden), die eine Klasse enthalten muss, wenn sie die Schnittstelle implementiert. In Android ist eine CharSequence ist ein Oberbegriff für verschiedene Arten von Textstrings. Hier sind einige der häufigsten:

(Sie können mehr über die Unterschiede zwischen diesen Methoden lesen aquí .)

Wenn Sie eine CharSequence Objekt, dann ist es tatsächlich ein Objekt einer der Klassen, die die CharSequence . Zum Beispiel:

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

Der Vorteil einer allgemeinen Dachform wie CharSequence ist, dass Sie mehrere Typen mit einer einzigen Methode behandeln können. Wenn ich zum Beispiel eine Methode habe, die eine CharSequence als Parameter übergeben, könnte ich eine String oder eine SpannableStringBuilder und es würde mit beiden umgehen.

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

Zeichenfolge

Man könnte sagen, dass ein String ist nur eine Art von CharSequence . Doch im Gegensatz zu CharSequence Es handelt sich um eine echte Klasse, aus der Sie Objekte erstellen können. Sie könnten also Folgendes tun:

String myString = new String();

aber das können Sie nicht tun:

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

Desde CharSequence ist nur eine Liste von Regeln, die String konform ist, könnten Sie dies tun:

CharSequence myString = new String();

Das bedeutet, dass jedes Mal, wenn eine Methode nach einem CharSequence ist es in Ordnung, ihm eine String .

String myString = "hello";
getLength(myString); // OK

// ...

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

Das Gegenteil ist jedoch nicht der Fall. Wenn die Methode eine String können Sie ihm nicht etwas übergeben, von dem nur allgemein bekannt ist, dass es ein CharSequence denn es könnte sich tatsächlich um eine SpannableString oder eine andere Art von CharSequence .

CharSequence myString = "hello";
getLength(myString); // error

// ...

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

7voto

Phil Lello Punkte 7839

Dies ist mit Sicherheit auf die Leistung zurückzuführen. Stellen Sie sich zum Beispiel einen Parser vor, der einen 500k ByteBuffer mit Zeichenketten durchläuft.

Es gibt 3 Möglichkeiten, den Inhalt der Zeichenkette zurückzugeben:

  1. Erstellt einen String[] zur Parse-Zeit, ein Zeichen nach dem anderen. Dies wird eine beträchtliche Zeit in Anspruch nehmen. Wir können == anstelle von .equals verwenden, um zwischengespeicherte Referenzen zu vergleichen.

  2. Erstellen eines int[] mit Offsets zur Parse-Zeit, dann dynamisch erstellen String, wenn ein get() geschieht. Jeder String wird ein neues Objekt sein, also keine Zwischenspeicherung der zurückgegebenen Werte und Verwendung von ==

  3. Erstellt eine CharSequence[] zum Zeitpunkt des Parsens. Da keine neuen Daten gespeichert werden (außer den Offsets im Byte-Puffer), ist der Parsing-Aufwand viel geringer als bei #1. Zur Get-Zeit muss kein String erstellt werden, daher ist die Get-Leistung gleich wie bei #1 (viel besser als #2), da wir nur einen Verweis auf ein bestehendes Objekt zurückgeben.

Zusätzlich zu den Verarbeitungsvorteilen, die Sie durch die Verwendung von CharSequence erzielen, verringern Sie auch den Speicherbedarf, da keine Daten dupliziert werden. Wenn Sie z. B. einen Puffer mit 3 Textabschnitten haben und entweder alle 3 oder einen einzelnen Abschnitt zurückgeben möchten, benötigen Sie 4 Strings, um dies darzustellen. Mit CharSequence benötigen Sie nur einen Puffer mit den Daten und 4 Instanzen einer CharSequence-Implementierung, die den Anfang und die Länge verfolgt.

7 Stimmen

Referenzen plz. klingt wie zufällig erraten, was vor sich geht. auch ich nicht finden Ihr Argument gültig. man könnte einfach speichern die 500k Bytebuffer als eine Zeichenfolge in erster Linie und nur zurückgeben Teilstrings, die verrückt schnell ist, und viel mehr gemeinsam.

7 Stimmen

@kritzikratzi - ab JDK7 teilt substring auf String nicht mehr das zugrunde liegende Array und ist nicht "wahnsinnig schnell". Es dauert O(N) Zeit in der Länge der Teilzeichenkette und erzeugt eine Kopie der zugrunde liegenden Zeichen jedes Mal, wenn Sie es aufrufen (so eine Menge von Müll).

0 Stimmen

@kritzikratzi Ich glaube, der Grund für die Änderung ist, dass die ursprüngliche Zeichenfolge für die Lebensdauer aller Teilzeichenfolgen erhalten bleibt, wenn die Kopie nicht erstellt wird. Da Teilzeichenketten in der Regel nur kleine Teile der ursprünglichen Zeichenkette sind und je nach ihrer Verwendung unendlich lange bestehen können, würde dies oft zu noch mehr Müll führen, wenn die Teilzeichenketten viel länger als die ursprüngliche Zeichenkette verwendet werden. Ein interessanter Ansatz könnte sein, zu bestimmen, ob eine Kopie auf der Grundlage des Verhältnisses zwischen der Größe der Teilzeichenkette und der Größe der übergeordneten Zeichenkette erstellt werden soll oder nicht, aber dazu müssten Sie Ihre eigene Methode entwickeln. CharSequence die Implementierung dafür.

0voto

htlbydgod Punkte 133

CharSequence ist eine Schnittstelle und String setzt sie um. Sie können eine instanziierte String aber das konnten Sie nicht tun, weil CharSequence da es sich um eine Schnittstelle handelt. Weitere Implementierungen finden Sie in CharSequence auf der offiziellen Java-Website.

-5voto

CharSequence ist eine lesbare Folge von Zeichenwerten, die String implementiert. Sie hat 4 Methoden

  1. charAt(int index)
  2. length()
  3. subSequence(int start, int end)
  4. toString()

Bitte beachten Sie die Dokumentation CharSequence-Dokumentation

6 Stimmen

CharSequence implementiert nicht String . Aber auch das Gegenteil ist der Fall.

2 Stimmen

Bitte entfernen Sie diese unsinnige Antwort

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X