Pourquoi CharSequence ne définit-il pas contient (CharSequence)?

11

Cela s'applique à la fois à Java SE et à Android, car les contrats sont identiques.

CharSequencene définit pas de contains(CharSequence)méthode. Je n'arrive pas à trouver une raison pour laquelle, et l'inclure serait très utile, évitant d'avoir à appeler CharSequence#toString()pour vérifier une séquence de caractères.

Par exemple, dans Android, les utilisateurs sont obligés d'appeler Editable#toString()pour voir s'il contient une séquence de caractères, bien que des Editableimplémentations CharSequence, qui peuvent être évitées si elles sont CharSequencedéfinies contains(CharSequence).

Quelle est l'idée derrière ce choix de conception? Est-ce un oubli potentiel ou y a-t-il une raison de conception à cela?

Vince Emigh
la source

Réponses:

10

Le but CharSequenceest de fournir une vue en lecture seule à une séquence de caractères, et c'est tout. Cette interface ne fournit aucune manipulation de chaîne ni méthode de recherche. Ce sont hors de portée.

Le principe de ségrégation d'interface suggère que les clients d'un type ne devraient pas dépendre de méthodes qu'ils n'utilisent pas. Par conséquent, une interface ne doit déclarer que l'ensemble minimal utile. Si un cas d'utilisation différent nécessite des méthodes différentes, il doit y avoir une interface différente.

Un client qui n'a besoin que d'une source de caractères n'a probablement pas besoin de méthodes de recherche.

Il est bien sûr possible d'exagérer ce principe et de se retrouver avec mille petites interfaces. Ce n'est pas bon non plus. Ainsi, l' CharSequenceinterface ne contient pas seulement le minimum charAt()et les length()méthodes, mais aussi la méthode de commodité profondément liée subSequence(). (Une CharSequence peut probablement fournir une vue sur une sous-séquence sans copie de chaîne, c'est pourquoi cela devrait être une méthode d'instance). La spécification toString()est OK car cette méthode serait de toute façon héritée de Object. Les méthodes chars()et l' codePoints()adapter CharSequenceà une Streaminterface. Comme ce sont des méthodes par défaut, elles n'imposent pas d'exigences supplémentaires pour les classes implémentant CharSequence.

Le CharSequencetype est utile lorsqu'une méthode a besoin d'une source de caractères générique sans spécifier une implémentation particulière (par exemple String vs. CharBuffer vs. StringBuilder). Les méthodes String#join()et String#contains()sont de bons exemples d'utilisation du par CharSequence.

Il n'est pas nécessaire CharSequencede fournir une contains()méthode car elle peut être implémentée en externe. Bien que Java n'ait pas la commodité des méthodes d'extension de C #, une méthode statique est essentiellement la même chose. Donc, au lieu de boolean Editable#contains(CharSequence needle)vous, vous auriez un static boolean contains(CharSequence haystack, CharSequence needle). Les algorithmes de recherche de chaînes sont un sujet d'informatique bien étudié. Différents algorithmes avec différents compromis sont facilement disponibles.

Lectures complémentaires:

amon
la source
2
Vous mentionnez « Cette interface ne fournit aucune manipulation de chaînes ou méthodes à la recherche. Ce sont hors de portée. », Mais containsn'est pas une méthode de mutation, et il ne les méthodes de recherche d'exist ( charAt), alors comment cette application ?. En outre, " Parce que ce sont des méthodes par défaut, elles n'imposent pas d'exigences supplémentaires pour les classes implémentant CharSequence. " - Ne pourrait pas containsêtre implémenté par défaut via l'impl return to String().contains(...), supprimant l'exigence pour les classes à implémenter?
Vince Emigh
1
@VinceEmigh Oui, contains()pourrait être une méthode par défaut. S'il existait, il ne devrait pas être implémenté en termes de, String#containsmais dans l'autre sens: String devrait utiliser l'implémentation CharSequence. C'est charAt()différent. Il n'implémente pas d'algorithme de recherche, c'est une partie cruciale du CharSequence: sans lui, le contenu ne pourrait pas être copié dans un type différent String. Les flux sont une partie cruciale de Java8, et l'ajout de ces méthodes par défaut est conforme aux ajouts à d'autres interfaces comme Collection.
amon