Warum definiert CharSequence nicht enthält (CharSequence)?

11

Dies gilt sowohl für Java SE als auch für Android, da die Verträge identisch sind.

CharSequencedefiniert keine contains(CharSequence)Methode. Ich kann anscheinend keinen Grund finden, warum und es wäre sehr nützlich, wenn ich nicht anrufen müsste CharSequence#toString(), um nach einer Folge von Zeichen zu suchen .

In Android müssen Benutzer beispielsweise anrufen, Editable#toString()um festzustellen, ob es eine Folge von Zeichen enthält, wenn auch EditableImplementierungen CharSequence, die bei der CharSequenceDefinition vermieden werden können contains(CharSequence).

Welche Idee steckt hinter dieser Designentscheidung? Ist es ein mögliches Versehen oder gibt es einen Designgrund dafür?

Vince Emigh
quelle

Antworten:

10

Der Zweck von CharSequencebesteht darin, eine schreibgeschützte Ansicht für eine Zeichenfolge bereitzustellen, und das war's. Diese Schnittstelle bietet keine Methoden zur Manipulation oder Suche von Zeichenfolgen. Diese liegen außerhalb des Anwendungsbereichs.

Das Prinzip der Schnittstellentrennung legt nahe, dass Clients eines Typs nicht von Methoden abhängen sollten, die sie nicht verwenden. Daher sollte eine Schnittstelle nur den minimalen nützlichen Satz deklarieren. Wenn ein anderer Anwendungsfall andere Methoden erfordert, sollte es eine andere Schnittstelle geben.

Ein Client, der nur eine Zeichenquelle benötigt, benötigt wahrscheinlich keine Suchmethoden.

Es ist natürlich möglich, dieses Prinzip zu übertreiben und am Ende tausend kleine Schnittstellen zu erhalten. Das ist auch nicht gut. Die CharSequenceBenutzeroberfläche enthält also nicht nur die Minimal- charAt()und length()Methoden, sondern auch die eng verwandte Convenience-Methode subSequence(). (Eine CharSequence kann wahrscheinlich eine Ansicht auf eine Teilsequenz ohne eine Zeichenfolgenkopie bereitstellen, weshalb dies eine Instanzmethode sein sollte.) Die Angabe toString()ist in Ordnung, da diese Methode ohnehin von geerbt würde Object. Die Methoden chars()und codePoints()passen sich CharSequencean eine StreamSchnittstelle an. Da dies Standardmethoden sind, stellen sie keine zusätzlichen Anforderungen für die Implementierung von Klassen CharSequence.

Der CharSequenceTyp ist nützlich, wenn eine Methode eine generische Zeichenquelle benötigt, ohne eine bestimmte Implementierung anzugeben (z. B. String vs. CharBuffer vs. StringBuilder). Die String#join()und String#contains()Methoden sind gute Beispiele für die Verwendung von CharSequences.

Es ist nicht erforderlich CharSequence, eine contains()Methode bereitzustellen , da diese extern implementiert werden kann. Während Java nicht die Bequemlichkeit der Erweiterungsmethoden von C # bietet, ist eine statische Methode im Wesentlichen dasselbe. Also statt boolean Editable#contains(CharSequence needle)du hättest ein static boolean contains(CharSequence haystack, CharSequence needle). String-Suchalgorithmen sind ein gut untersuchtes Informatik-Thema. Verschiedene Algorithmen mit unterschiedlichen Kompromissen sind leicht verfügbar.

Weiterführende Literatur:

amon
quelle
2
Sie erwähnen „ Diese Schnittstelle bietet keine String - Manipulation oder Suchmethoden. Das ist außerhalb des Gültigkeitsbereiches. “, Aber containsist kein Mutationsverfahren, und es ist exist Suchmethoden ( charAt), so wie funktioniert dies gilt ?. " Da dies Standardmethoden sind, stellen sie keine zusätzlichen Anforderungen für Klassen, die CharSequence implementieren. " - Konnte nicht containsstandardmäßig über das Impl implementiert werden return to String().contains(...), wodurch die Anforderung für die Implementierung von Klassen entfernt wurde.
Vince Emigh
1
@VinceEmigh Ja, contains()könnte eine Standardmethode sein. Wenn es existiert, sollte es nicht implementiert werden, String#containssondern umgekehrt: String sollte die CharSequence-Implementierung verwenden. Das charAt()ist anders. Es implementiert keinen Suchalgorithmus, es ist ein entscheidender Teil des CharSequence: Ohne ihn könnte der Inhalt nicht in einen anderen Typ wie kopiert werden String. Streams sind ein wesentlicher Bestandteil von Java8, und das Hinzufügen dieser Standardmethoden entspricht dem Hinzufügen zu anderen Schnittstellen wie Collection.
Amon