これは、契約が同一であるため、Java SEおよびAndroidの両方に適用されます。
CharSequence
はcontains(CharSequence)
メソッドを定義していません。文字列を確認するためにCharSequence#toString()
を呼び出す必要をなくし、それを含めることが非常に役立つ理由を見つけることができないようです。
たとえばAndroidでは、Editable
はCharSequence
を実装していますが、CharSequence
を実装しているにもかかわらず、ユーザーはEditable#toString()
を呼び出して文字のシーケンスが含まれているかどうかを確認する必要があります。 $ var] _定義済みcontains(CharSequence)
。
このデザインの選択の背後にあるアイデアは何ですか?見落としの可能性はありますか、それとも設計上の理由がありますか?
CharSequence
のポイントは、文字シーケンスに読み取り専用のビューを提供することです。それだけです。このインターフェイスは、文字列操作または検索メソッドを提供しません。それらは範囲外です。
インターフェイス分離の原則では、タイプのクライアントは、使用しないメソッドに依存するべきではないことを示唆しています。したがって、インターフェースは、最小限の有用なセットのみを宣言する必要があります。別のユースケースで別のメソッドが必要な場合は、別のインターフェースが必要です。
キャラクターソースのみを必要とするクライアントは、おそらく検索メソッドを必要としません。
もちろん、この原則をやりすぎて、1,000個の小さなインターフェースになる可能性もあります。それも良くありません。したがって、CharSequence
インターフェースには、最小限のcharAt()
メソッドとlength()
メソッドだけでなく、関連性の高い便利なメソッドsubSequence()
も含まれています。 (CharSequenceは、文字列のコピーなしでサブシーケンスのビューを提供できる可能性が高いため、これがインスタンスメソッドである必要があります)。 toString()
の指定は、そのメソッドがObject
から継承されるため、問題ありません。メソッドchars()
およびcodePoints()
は、CharSequence
をStream
インターフェースに適合させます。これらはデフォルトのメソッドであるため、CharSequence
を実装するクラスに追加の要件を課すことはありません。
CharSequence
タイプは、特定の実装を指定せずにメソッドが一般的な文字ソースを必要とする場合に便利です(例:StringとCharBufferとStringBuilderの比較)。 String#join()
およびString#contains()
メソッドは、CharSequence
sを使用する良い例です。
外部で実装できるため、CharSequence
がcontains()
メソッドを提供する必要はありません。 JavaにはC#の拡張メソッドの利便性はありませんが、静的メソッドは基本的に同じものです。したがって、boolean Editable#contains(CharSequence needle)
の代わりにstatic boolean contains(CharSequence haystack, CharSequence needle)
を使用します。 文字列検索アルゴリズム はよく研究されたコンピューターサイエンスのトピックであり、異なるトレードオフの異なるアルゴリズムがすぐに利用できます。
参考文献:
ウィキペディア: 文字列検索アルゴリズム 。特に Boyer-Mooreアルゴリズム を参照してください。
ウィキペディア: インターフェース分離の原則 。
ロバートC.マーティン:インターフェース分離の原則( GoogleドライブのPDF 、 インターネットアーカイブのウェイバックのPDFマシン )。