为什么CharSequence不定义contains(CharSequence)?


11

这适用于Java SE和Android,因为合同是相同的。

CharSequence没有定义contains(CharSequence)方法。我似乎找不到原因,并且包括它非常有用,可以防止需要调用CharSequence#toString()以检查字符序列。

例如,在Android中,用户被迫致电Editable#toString()查看它是否包含字符序列(尽管是Editable实现)CharSequence,但如果CharSequence定义可以避免contains(CharSequence)

这种设计选择背后的想法是什么?是潜在的监督,还是有设计原因?

Answers:


10

重点CharSequence是为字符序列提供只读视图,仅此而已。此接口不提供任何字符串操作或搜索方法。这些超出范围。

接口隔离原则建议类型的客户端不应依赖于他们不使用的方法。因此,接口应仅声明最小有用集。如果不同的用例需要不同的方法,则应该有不同的接口。

仅需要字符源的客户端可能不需要搜索方法。

当然有可能过度使用该原理并最终形成一千个小接口。那也不好。因此,CharSequence接口不仅包含minimum charAt()length()method,还包含与之息息相关的便捷方法subSequence()。(CharSequence可能可以提供不带字符串副本的子序列视图,这就是为什么应该将其作为实例方法的原因)。指定toString()是可以的,因为无论如何该方法都将继承Object。方法chars()codePoints()适应CharSequenceStream接口。由于这些是默认方法,因此它们不对类实现施加其他要求CharSequence

CharSequence当方法需要通用字符源而不指定特定实现时(例如,String vs. CharBuffer vs. StringBuilder),该类型很有用。该String#join()String#contains()方法是用很好的例子CharSequence秒。

不必CharSequence提供一种contains()方法,因为它可以在外部实现。尽管Java不具备C#扩展方法的便利性,但静态方法本质上是一回事。因此,代替boolean Editable#contains(CharSequence needle)您将有一个static boolean contains(CharSequence haystack, CharSequence needle)字符串搜索算法是一个经过充分研究的计算机科学主题。具有不同权衡的不同算法很容易获得。

进一步阅读:


2
您提到“ 此接口不提供任何字符串操作或搜索方法。它们不在范围内。 ”,但contains不是突变方法,并且确实存在搜索方法(charAt),那么这如何应用?另外,“ 因为这些是默认方法,所以它们不对实现CharSequence的类施加其他要求。 ”-无法contains通过impl作为默认值实现return to String().contains(...),从而消除了对实现类的要求吗?
文斯·艾米

1
@VinceEmigh是的,contains()可以是默认方法。如果存在,则不应以String#contains相反的方式实现它:String应该使用CharSequence实现。的charAt()是不同的。它没有实现搜索算法,它是的关键部分CharSequence:没有它,内容将无法复制到其他类型,例如String。流是Java8的重要组成部分,添加这些默认方法与添加其他接口(如)是一致的Collection
阿蒙(Amon)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.