Чому параметр CharSequence не містить (CharSequence)?


11

Це стосується обох Java SE та Android, оскільки договори однакові.

CharSequenceне визначає contains(CharSequence)метод. Я не можу знайти причину, чому, в тому числі, це було б дуже корисно, запобігаючи необхідності дзвонити, CharSequence#toString()щоб перевірити послідовність символів.

Наприклад, в Android користувачі змушені телефонувати, Editable#toString()щоб побачити, чи містить вона послідовність символів, хоч і Editableреалізацію CharSequence, якої можна уникнути, якщо CharSequenceце визначено contains(CharSequence).

Яка ідея цього вибору дизайну? Це потенційний нагляд чи є причина цього для проектування?

Відповіді:


10

Сенс CharSequenceполягає у наданні перегляду символів лише для читання, і це все. Цей інтерфейс не забезпечує жодних методів маніпуляцій із рядками чи пошуку. Це поза сферою застосування.

Принцип розбиття інтерфейсу передбачає, що клієнти типу не повинні залежати від методів, які вони не використовують. Тому інтерфейс повинен оголошувати лише мінімальний корисний набір. Якщо для іншого випадку використання потрібні різні методи, має бути інший інтерфейс.

Клієнт, який потребує лише джерела символів, швидше за все, не потребує методів пошуку.

Звичайно, можна перестаратися з цим Принципом і отримати тисячу маленьких інтерфейсів. Це теж не добре. Таким чином, CharSequenceінтерфейс містить не лише мінімум charAt()та length()методи, але й глибоко пов'язаний метод зручності subSequence(). (CharSequence, ймовірно, може забезпечити подання на підпорядкування без рядкової копії, тому це має бути метод екземпляра). Вказати toString()все нормально, оскільки цей метод у будь-якому випадку буде успадкований Object. Методи chars()та codePoints()адаптація a CharSequenceдо Streamінтерфейсу. Оскільки це методи за замовчуванням, вони не пред'являють додаткових вимог до впровадження класів CharSequence.

CharSequenceТипу корисно , коли метод необхідний загальний джерело символів без зазначення конкретної реалізації (наприклад , рядок проти CharBuffer проти 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.
амон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.