在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内容:

  1. 在parsing时build立一个string[],一次一个字符。 这将花费大量的时间。 我们可以使用==代替.equals来比较caching的引用。

  2. 在parsing时使用偏移量构build一个int [],然后在get()发生时dynamic构buildString。 每个string将是一个新的对象,所以没有caching返回值和使用==

  3. 在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种方法

  1. charAt(int index)
  2. 长度()
  3. subSequence(int start,int end)
  4. 的toString()

请参阅文档CharSequence文档