在Java中CharSequence VSstring?
在Android中编程,大部分文本值都在CharSequence
。
这是为什么? 什么是好处,什么是使用CharSequence
超过string的主要影响?
主要的区别是什么?在使用它们的时候会遇到什么样的问题?从一个到另一个?
string是CharSequences ,所以你可以使用string,而不用担心。 Android只是试图通过允许你指定其他的CharSequence对象,比如StringBuffers来帮助你。
我相信最好使用CharSequence。 原因是String实现了CharSequence,所以你可以传递一个string到CharSequence中,但是你不能把一个CharSequence传递到一个string中,因为CharSequence不会实现String。 另外,在Android中, EditText.getText()
方法返回一个Editable,它也实现了CharSequence,并且可以轻松地将其传入一个,而不容易转换成一个String。 CharSequence处理所有!
这个类图可以帮助你看到Java 7/8中stringtypes的大图。 我不确定是否所有这些都出现在Android中,但总体上下文可能仍然对您有用。
另外,请注意对已接受答案的评论。 CharSequence
接口被改装到现有的类结构,所以有一些重要的细节( equals()
和hashCode()
)。 请注意,在类/接口上标记的Java(1,2,4和5)的各种版本 – 多年来都有一些stream失。 理想情况下, CharSequence
从一开始就已经到位,但这就是生活。
一般来说,使用界面可以让您以最小的附带损害来改变实现。 尽pipejava.lang.String是超级stream行的,但是在某些情况下可能需要使用另一个实现。 通过围绕CharSequences而不是string构buildAPI,代码给了一个机会来做到这一点。
这几乎肯定是性能的原因。 例如,想象一个经过一个包含string的500k ByteBuffer的parsing器。
有三种方法返回string内容:
-
在parsing时build立一个string[],一次一个字符。 这将花费大量的时间。 我们可以使用==代替.equals来比较caching的引用。
-
在parsing时使用偏移量构build一个int [],然后在get()发生时dynamic构buildString。 每个string将是一个新的对象,所以没有caching返回值和使用==
-
在parsing时build立一个CharSequence []。 由于没有新的数据存储(除了字节缓冲区的偏移量),parsing要低得多#1。 在得到的时候,我们不需要build立一个string,所以性能等于#1(比#2好得多),因为我们只是返回一个对现有对象的引用。
除了使用CharSequence获得的处理收益外,还可以通过不复制数据来减less内存占用量。 例如,如果您有一个包含3段文本的缓冲区,并且要返回全部3个或一个段落,则需要4个string来表示这个。 使用CharSequence,你只需要1个缓冲区的数据,一个CharSequence实现的4个实例跟踪开始和长度。
在实际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());
为CharSequence
CharSequence
是一个接口,而不是一个实际的类。 一个接口只是一组规则(方法),如果一个类实现了接口,它就必须包含这些规则。 在Android中, CharSequence
是各种types文本string的保护伞。 这里有一些常见的:
-
String
(不可修改的文本,没有样式跨度) -
StringBuilder
(可变文本没有样式跨度) -
SpannableString
(具有样式跨度的不可变文本) -
SpannableStringBuilder
(具有样式跨度的可变文本)
(你可以在这里阅读更多关于这些差异的内容。)
如果你有一个CharSequence
对象,那么它实际上是实现CharSequence
的一个类的一个对象。 例如:
CharSequence myString = "hello"; CharSequence mySpannableStringBuilder = new SpannableStringBuilder();
像CharSequence
这样的通用伞型的好处是你可以用一种方法处理多种types。 例如,如果我有一个将CharSequence
作为参数的方法,我可以传递一个String
或一个SpannableStringBuilder
,它可以处理任何一个。
public int getLength(CharSequence text) { return text.length(); }
串
你可以说一个String
只是一种CharSequence
。 但是,与CharSequence
不同,它是一个实际的类,所以你可以从中创build对象。 所以你可以这样做:
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
或者其他types的CharSequence
。
CharSequence myString = "hello"; getLength(myString); // error // ... public int getLength(String text) { return text.length(); }
CharSequence
是一个接口, String
实现它。 你可以实例化一个String
但是你不能为CharSequence
做这个,因为它是一个接口。 您可以在官方Java网站的CharSequence
中find其他实现。
CharSequence是实现String的char值的可读序列。 它有4种方法
- charAt(int index)
- 长度()
- subSequence(int start,int end)
- 的toString()
请参阅文档CharSequence文档