在Android中进行编程,大多数文本值都在CharSequence
。
为什么?有什么好处,使用CharSequence
而不是String
的主要影响是什么?
使用它们时,主要区别是什么,预期会出现什么问题,以及从一个问题转换为另一个问题?
答案 0 :(得分:329)
Strings are CharSequences,所以你可以使用字符串而不用担心。 Android只是通过允许您指定其他CharSequence对象(如StringBuffers。
)来尝试提供帮助答案 1 :(得分:43)
这个类图可以帮助您了解Java 7/8中字符串类型的全貌。我不确定Android中是否存在所有这些内容,但总体情况可能仍然对您有用。
另请注意accepted Answer上的评论。 CharSequence
界面被改装到现有的类结构上,因此有一些重要的细微之处(equals()
& hashCode()
)。请注意在类/接口上标记的各种版本的Java(1,2,4和5) - 这些年来相当多的流失。理想情况下CharSequence
从一开始就会存在,但这就是生活。
答案 2 :(得分:36)
我认为最好使用CharSequence。原因是String实现了CharSequence,因此您可以将String传递给CharSequence,但是您无法将CharSequence传递给String,因为CharSequence不会实现String。另外,在Android中,EditText.getText()
方法返回一个Editable,它也实现了CharSequence,可以很容易地传递给一个,而不是很容易地传递给一个String。 CharSequence处理所有!
答案 3 :(得分:22)
通常使用界面可以让您以最小的附带损害改变实施方式。虽然java.lang.String非常受欢迎,但在某些情况下可能需要使用另一个实现。通过围绕CharSequences而不是字符串构建API,代码为人们提供了这样做的机会。
答案 4 :(得分:8)
这几乎可以肯定是性能原因。例如,假设一个解析器通过一个包含字符串的500k ByteBuffer。
返回字符串内容有三种方法:
在分析时构建一个String [],一次一个字符。这将花费相当多的时间。我们可以使用==而不是.equals来比较缓存的引用。
在解析时使用偏移量构建一个int [],然后在get()发生时动态构建String。每个String都是一个新对象,因此没有缓存返回值并使用==
在解析时构建CharSequence []。由于没有存储新数据(除了偏移到字节缓冲区之外),解析比#1低得多。在get get时,我们不需要构建一个String,因此get性能等于#1(比#2好得多),因为我们只返回对现有对象的引用。
除了使用CharSequence获得的处理增益之外,您还可以通过不复制数据来减少内存占用。例如,如果您有一个包含3段文本的缓冲区,并且想要返回所有3段或单个段落,则需要4个字符串来表示这一点。使用CharSequence,您只需要一个带有数据的缓冲区,以及一个跟踪开始和长度的CharSequence实现的4个实例。
答案 5 :(得分:7)
实际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());
答案 6 :(得分:3)
CharSequence
是一个接口,而不是一个实际的类。接口只是一组规则(方法),如果实现接口,则类必须包含这些规则。在Android中,CharSequence
是各种类型文本字符串的保护伞。以下是一些常见的内容:
String
(不带样式范围的不可变文本)StringBuilder
(没有样式跨度的可变文本)SpannableString
(带样式范围的不可变文本)SpannableStringBuilder
(带样式范围的可变文本)(您可以详细了解这些here之间的差异。)
如果你有一个CharSequence
对象,那么它实际上是一个实现CharSequence
的类的对象。例如:
CharSequence myString = "hello";
CharSequence mySpannableStringBuilder = new SpannableStringBuilder();
拥有像CharSequence
这样的通用保护伞类型的好处是,您可以使用单一方法处理多种类型。例如,如果我有一个方法以CharSequence
作为参数,我可以传入String
或SpannableStringBuilder
,它会处理任何一个。
public int getLength(CharSequence text) {
return text.length();
}
你可以说String
只是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
或其他类型{ {1}}。
CharSequence
答案 7 :(得分:0)
CharSequence
是一个接口,String
实现了它。您可以实例化String
,但由于它是一个接口,您无法对CharSequence
执行此操作。您可以在官方Java网站的CharSequence
中找到其他实现。
答案 8 :(得分:-4)
CharSequence是一个可读的char值序列,它实现了String。它有4种方法