回答:
文字列はCharSequencesであるため、文字列を使用するだけでかまいません。Androidは、StringBuffersなどの他のCharSequenceオブジェクトも指定できるようにすることで、単に役立つようにしています。
CharSequence
javadocの警告に注意してください。このインターフェースは、equals
およびhashCode
メソッドの一般的な規約を洗練していません。CharSequence
したがって、実装する2つのオブジェクトを比較した結果は、一般にundefinedです。各オブジェクトは異なるクラスによって実装される可能性があり、各クラスがそのインスタンスを他のインスタンスと等しいかどうかテストできるとは限りません。したがって、任意のCharSequence
インスタンスをセットの要素として、またはマップのキーとして使用することは不適切です。
CharSequence
JDK 1.4の改良版であり、文字シーケンスを含むオブジェクトへの限定目的の共通インターフェースを導入しました。これらのオブジェクトの一部には他の状態が含まれているためObject.equals
、「同じ文字シーケンスを含む」と定義しても意味がない場合があります。CharBuffer
たとえばNIOは、他の多くの文字を保持している可能性があるにもかかわらず、position
との間の文字のみを公開します。limit
CharSequence
equals
/ hashCode
オンObject
になっています...
Object
またはのどちらにも設計上のバグはありませんCharSequence
。実装間の等価性を提供するためにインターフェイスは必要ありません。インターフェイスCollection
間の同等性を提供するために2つのは必要ありませんが、必要に応じて2つを使用Collection
できます。IMHO CharSequence
は入力に限定され、戻り値の型にはあまり使用されません。
CharSequence
=インターフェースString
=具体的な実装CharSequence
あるインターフェースが。String
はそのようなクラスの1つであり、の具体的な実装ですCharSequence
。あなたが言った:
あるものから別のものへの変換
からの変換はありませんString
。
String
オブジェクトがありますCharSequence
。CharSequence
がを生成できString
ます。を呼び出しCharSequence::toString
ます。CharSequence
がたまたまの場合、String
メソッドは自身のオブジェクトへの参照を返します。言い換えれば、すべてのはString
あるCharSequence
が、すべてではないCharSequence
ですString
。
Androidでのプログラミングでは、ほとんどのテキスト値はCharSequenceで期待されます。
何故ですか?文字列よりもCharSequenceを使用する主な影響は何ですか?
一般に、インターフェースへのプログラミングは、具象クラスへのプログラミングよりも優れています。これにより柔軟性が生まれるため、他のコードを壊すことなく、特定のインターフェースの具体的な実装を切り替えることができます。
さまざまな状況でさまざまなプログラマーが使用するAPIを開発するときは、可能な限り最も一般的なインターフェースを提供および取得するようにコードを記述します。これにより、呼び出し側のプログラマは、特定のコンテキストに最適な実装である、そのインターフェースのさまざまな実装を自由に使用できます。
たとえば、Java Collections Frameworkを見てください。あなたのAPIを提供したり、オブジェクトの順序付きコレクションを取る場合は、使用して、あなたのメソッドを宣言するList
のではなくArrayList
、LinkedList
または任意の他のサードパーティの実装List
。
複数の場所で使用されるAPIを作成するのではなく、1つの特定の場所でコードによってのみ使用される簡単なメソッドを作成する場合、特定の具象ではなく、より一般的なインターフェイスを使用する必要はありません。クラス。しかし、それでも、できる限り一般的なインターフェースを使用することは害になります。
主な違いは何ですか、それらを使用しているときに予想される問題は、
String
あなたが知っていると、あなたはあなたが完全にメモリにある単一のテキストを持ち、不変です。CharSequence
と、具体的な実装の特定の機能が何であるかがわかりません。CharSequence
オブジェクトは、テキストの巨大な塊を表し、したがって、メモリへの影響を持っているかもしれません。または、個別に追跡されるテキストのチャンクが多数ある場合があります。これらのテキストは、を呼び出すときにつなぎ合わせる必要があるtoString
ため、パフォーマンスの問題があります。この実装では、リモートサービスからテキストを取得することもあるので、レイテンシに影響します。
と別のものに変換しますか?
通常、前後に変換することはありません。AがString
ありますCharSequence
。あなたの方法は、それが取ることを宣言した場合CharSequence
、呼び出しプログラマが渡すことString
のオブジェクトを、またはのような何か他のもの渡すことStringBuffer
かをStringBuilder
。メソッドのコードは、渡されたものを何でも使用して、CharSequence
メソッドのいずれかを呼び出します。
変換に最も近いのは、コードがを受け取り、CharSequence
が必要であることがわかっている場合ですString
。おそらく、インターフェースに書き込まれるのString
ではなく、クラスに書き込まれた古いコードとインターフェースしている可能性がありCharSequence
ます。または、コードがテキストで集中的に機能する場合があります。たとえば、繰り返しループしたり、分析したりします。その場合、パフォーマンスヒットを1回だけ受けたいので、最初に呼び出しますtoString
。次に、完全にメモリ内にある1つのテキストであることがわかっているものを使用して作業を続行します。
承認された回答に加えられたコメントに注意してください。CharSequence
インターフェイスは、既存のクラス構造に改造されたので、いくつかの重要な微妙な点は、(あるequals()
とhashCode()
)。クラス/インターフェースにタグ付けされたJavaのさまざまなバージョン(1、2、4、および5)に注意してください。何年にもわたってかなりのチャーンが発生しています。理想的にCharSequence
は最初から存在していたはずですが、それは人生です。
以下のクラス図は、Java 7/8の文字列型の全体像を理解するのに役立ちます。これらすべてがAndroidに存在するかどうかはわかりませんが、全体的なコンテキストが役立つ場合があります。
CharSequenceを使用するのが最善だと思います。その理由は、文字列はCharSequenceを実装するため、文字列をCharSequenceに渡すことができます。ただし、CharSequenceは文字列を実装しないため、文字列にCharSequenceを渡すことはできません。また、Androidでは、このEditText.getText()
メソッドはEditableを返します。これは、CharSequenceも実装しているため、文字列に簡単に渡すことはできませんが、1つに簡単に渡すことができます。CharSequenceがすべてを処理します!
charSequence.toString()
これはほぼ間違いなくパフォーマンス上の理由です。たとえば、文字列を含む500kのByteBufferを通過するパーサーを想像してみてください。
文字列コンテンツを返すには、3つの方法があります。
一度に1文字ずつ、解析時にString []を作成します。これにはかなりの時間がかかります。.equalsの代わりに==を使用して、キャッシュされた参照を比較できます。
解析時にオフセットを使用してint []を作成し、get()が発生したときに動的にStringを作成します。各文字列は新しいオブジェクトになるため、戻り値のキャッシュや==の使用はありません
解析時にCharSequence []を作成します。(バイトバッファーへのオフセット以外の)新しいデータは保存されないため、解析は#1よりはるかに低くなります。取得時には、文字列を構築する必要がないため、既存のオブジェクトへの参照のみを返すため、取得パフォーマンスは#1(#2よりはるかに優れています)と同等です。
CharSequenceを使用することで得られる処理の向上に加えて、データを複製しないことでメモリフットプリントも削減します。たとえば、テキストの3つの段落を含むバッファーがあり、3つすべてまたは1つの段落を返す場合、これを表すには4つの文字列が必要です。CharSequenceを使用すると、データを含む1つのバッファーと、開始と長さを追跡するCharSequence実装の4つのインスタンスのみが必要になります。
CharSequence
、そのために独自の実装をロールする必要があります。
CharSequence
はインターフェースです。定義上、独自の実装がないため、説明する実装の詳細はありません。A String
は、インターフェースを実装するいくつかの具象クラスの1つですCharSequence
。そうString
ですCharSequence
。あなたはのパフォーマンスの詳細を比較することができString
対StringBuffer
対StringBuilder
ではなくCharSequence
。「CharSequenceを使用して得られる処理利益」を書いても意味がありません。
A CharSequence
はインターフェースであり、実際のクラスではありません。インターフェースは、インターフェースを実装する場合にクラスに含める必要がある一連のルール(メソッド)です。Androidでは、a CharSequence
はさまざまなタイプのテキスト文字列の傘です。一般的なものは次のとおりです。
String
(スタイリングスパンのない不変のテキスト)StringBuilder
(スタイリングスパンのない可変テキスト)SpannableString
(スタイルスパンを含む不変のテキスト)SpannableStringBuilder
(スタイリングスパンの可変テキスト)(これらの違いの詳細については、こちらをご覧ください。)
CharSequence
オブジェクトがある場合、それは実際にはを実装するクラスの1つのオブジェクトですCharSequence
。例えば:
CharSequence myString = "hello";
CharSequence mySpannableStringBuilder = new SpannableStringBuilder();
のような一般的なアンブレラ型を持つことの利点はCharSequence
、単一のメソッドで複数の型を処理できることです。たとえば、CharSequence
aをパラメーターとして受け取るメソッドがある場合、a String
またはa SpannableStringBuilder
を渡すことができ、どちらかを処理します。
public int getLength(CharSequence text) {
return text.length();
}
a String
は1種類にすぎないと言えCharSequence
ます。ただし、とは異なりCharSequence
、これは実際のクラスなので、そこからオブジェクトを作成できます。だからあなたはこれを行うことができます:
String myString = new String();
しかし、あなたはこれを行うことができません:
CharSequence myCharSequence = new CharSequence(); // error: 'CharSequence is abstract; cannot be instantiated
CharSequence
はString
準拠するルールのリストにすぎないので、次のようにすることができます。
CharSequence myString = new String();
この方法は、を要求任意の時間があることを意味しCharSequence
、それ与えるために罰金ですString
。
String myString = "hello";
getLength(myString); // OK
// ...
public int getLength(CharSequence text) {
return text.length();
}
ただし、その逆は当てはまりません。メソッドがString
パラメータをとる場合、CharSequence
それが実際にSpannableString
はや他の種類のである可能性があるため、であることが一般的に知られているものを渡すことはできませんCharSequence
。
CharSequence myString = "hello";
getLength(myString); // error
// ...
public int getLength(String text) {
return text.length();
}
CharSequenceは、Stringを実装する読み取り可能なchar値のシーケンスです。4つの方法があります
CharSequenceのドキュメントを参照してください
CharSequence
実装していませんString
。ただし、その逆は当てはまります。