Android でのプログラミングでは、ほとんどのテキスト値はCharSequence
.
何故ですか?CharSequence
overを使用する利点と主な影響は何String
ですか?
それらを使用し、あるものから別のものに変換する際に、主な違いは何ですか、またどのような問題が予想されますか?
Android でのプログラミングでは、ほとんどのテキスト値はCharSequence
.
何故ですか?CharSequence
overを使用する利点と主な影響は何String
ですか?
それらを使用し、あるものから別のものに変換する際に、主な違いは何ですか、またどのような問題が予想されますか?
文字列は CharSequencesであるため、文字列を使用するだけで問題ありません。Android は、StringBuffers などの他の CharSequence オブジェクトも指定できるようにすることで、役に立ちたいと考えているだけです。
CharSequence
= インターフェイスString
= 具体的な実装CharSequence
インターフェースです。String
はそのようなクラスの 1 つであり、 の具体的な実装ですCharSequence
。あなたが言った:
あるものから別のものへの変換
からの変換はありませんString
。
String
オブジェクトはCharSequence
.CharSequence
が を生成できString
ます。コールしCharSequence::toString
ます。CharSequence
が である場合String
、メソッドは独自のオブジェクトへの参照を返します。つまり、すべてString
が ですが、すべてがであるCharSequence
とは限りません。CharSequence
String
Android でのプログラミングでは、ほとんどのテキスト値が CharSequence であることが期待されます。
何故ですか?String ではなく CharSequence を使用することの利点と主な影響は何ですか?
一般に、インターフェイスへのプログラミングは、具体的なクラスへのプログラミングよりも優れています。これにより柔軟性が得られるため、他のコードを壊すことなく、特定のインターフェイスの具体的な実装を切り替えることができます。
さまざまなプログラマーがさまざまな状況で使用するAPIを開発するときは、可能な限り最も一般的なインターフェイスを提供および取得するようにコードを記述します。これにより、呼び出し元のプログラマーは、特定のコンテキストに最適な実装を使用して、そのインターフェイスのさまざまな実装を自由に使用できます。
たとえば、Java Collections Frameworkを見てください。API がオブジェクトの順序付けられたコレクションを提供または取得する場合は、 、 、または の他のサードパーティ実装ではなく、メソッドを使用して宣言しList
ます。ArrayList
LinkedList
List
複数の場所で使用される API を記述するのとは対照的に、1 つの特定の場所でコードによってのみ使用される簡単で汚い小さなメソッドを記述する場合、特定の具象ではなく、より一般的なインターフェイスを使用することを気にする必要はありません。クラス。しかし、それでも、できるだけ一般的なインターフェイスを使用するのは問題があります。
主な違いは何ですか。また、使用中に予想される問題は何ですか。
String
と、完全にメモリ内に 1 つのテキストがあり、不変であることがわかります。CharSequence
場合、具体的な実装の特定の機能が何であるかはわかりません。CharSequence
オブジェクトは膨大な量のテキストを表している可能性があるため、メモリへの影響があります。または、 を呼び出すときにつなぎ合わせる必要がある、個別に追跡されるテキストのチャンクが多数あるtoString
ため、パフォーマンスの問題が発生する場合があります。実装は、リモート サービスからテキストを取得している可能性もあるため、遅延に影響します。
あるものから別のものに変換しますか?
通常、前後に変換することはありません。AString
はですCharSequence
。メソッドが を受け取ると宣言した場合CharSequence
、呼び出し元のプログラマーはオブジェクトを渡すか、またはString
などの何かを渡すことができます。メソッドのコードは、渡されたものをそのまま使用し、任意のメソッドを呼び出します。StringBuffer
StringBuilder
CharSequence
変換に最も近いのは、コードが を受け取り、CharSequence
が必要であることがわかっている場合ですString
。おそらく、インターフェースにString
書かれたものではなく、クラスに書かれた古いコードとインターフェースしているのでしょうCharSequence
。または、繰り返しループしたり分析したりするなど、コードがテキストを集中的に処理する場合もあります。その場合、可能なパフォーマンス ヒットを 1 回だけ受けたいので、前もって呼び出しますtoString
。次に、完全にメモリ内にある単一のテキストであることがわかっているものを使用して作業を進めます。
受け入れられた Answerに対するコメントに注意してください。インターフェイスは既存のクラス構造に後付けされたCharSequence
ため、いくつかの重要な微妙な点 ( equals()
& hashCode()
) があります。Java のさまざまなバージョン (1、2、4、および 5) がクラス/インターフェースにタグ付けされていることに注意してください。理想的CharSequence
には最初から整っていたはずですが、それが人生です。
以下の私のクラス図は、Java 7/8 の文字列型の全体像を理解するのに役立つかもしれません。これらのすべてが Android に存在するかどうかはわかりませんが、全体的なコンテキストはまだ役立つかもしれません。
CharSequence を使用するのが最善だと思います。その理由は、String は CharSequence を実装しているため、String を CharSequence に渡すことができますが、CharSequence は String を実装していないため、CharSequence を String に渡すことはできません。また、Android では、このEditText.getText()
メソッドは Editable を返します。これは CharSequence も実装しており、String には簡単に渡すことはできませんが、簡単に渡すことができます。CharSequence がすべてを処理します。
一般に、インターフェースを使用すると、付随的な損害を最小限に抑えて実装を変更できます。java.lang.String は非常に人気がありますが、特定のコンテキストでは別の実装を使用したい場合があります。String ではなく CharSequences を中心に API を構築することにより、コードはそれを行う機会を与えます。
実際の Android コードで発生する問題は、それらを CharSequence.equals と比較することは有効ですが、必ずしも意図したとおりに機能するとは限らないことです。
EditText t = (EditText )getView(R.id.myEditText); // Contains "OK"
Boolean isFalse = t.getText().equals("OK"); // will always return false.
比較は
("OK").contentEquals(t.GetText());
これはほぼ確実にパフォーマンス上の理由です。たとえば、文字列を含む 500k ByteBuffer を通過するパーサーを想像してください。
文字列の内容を返す方法は 3 つあります。
一度に 1 文字ずつ、解析時に String[] を作成します。これにはかなりの時間がかかります。.equals の代わりに == を使用して、キャッシュされた参照を比較できます。
解析時にオフセットを使用して int[] を構築し、get() が発生したときに String を動的に構築します。各文字列は新しいオブジェクトになるため、返された値をキャッシュせず、== を使用しません
解析時に CharSequence[] を構築します。(バイト バッファーへのオフセットを除いて) 新しいデータは格納されないため、解析は #1 よりもはるかに低くなります。get 時には、String を作成する必要がないため、既存のオブジェクトへの参照を返すだけなので、get のパフォーマンスは #1 (#2 よりもはるかに優れています) と同等です。
CharSequence を使用すると処理が向上するだけでなく、データを複製しないことでメモリ フットプリントも削減できます。たとえば、テキストの 3 つの段落を含むバッファーがあり、3 つすべてまたは単一の段落のいずれかを返したい場合、これを表すには 4 つの文字列が必要です。CharSequence を使用すると、データを含む 1 つのバッファーと、開始と長さを追跡する CharSequence 実装の 4 つのインスタンスのみが必要になります。
CharSequence
インターフェースであり、それをString
実装します。をインスタンス化することはできますが、それはインターフェイスでString
あるためできません。CharSequence
他の実装についてCharSequence
は、Java の公式 Web サイトを参照してください。
CharSequence は、String を実装する char 値の読み取り可能なシーケンスです。それには4つの方法があります
ドキュメントを参照してください