450

在 Android 中编程,大多数文本值都应在CharSequence.

这是为什么?CharSequence使用over有什么好处,主要影响是String什么?

在使用它们以及从一种转换到另一种时,主要区别是什么,预计会出现哪些问题?

4

9 回答 9

354

字符串是 CharSequences,所以你可以只使用字符串而不用担心。Android 只是试图通过允许您指定其他 CharSequence 对象(如 StringBuffers)来提供帮助。

于 2009-06-26T13:45:38.593 回答
85

CharSequence= 接口
String= 具体实现

你说:

从一个转换到另一个

没有从String.

  • 每个String对象都是一个CharSequence
  • 每个都CharSequence可以产生一个String. 打电话CharSequence::toString。如果CharSequence恰好是 a String,则该方法返回对其自身对象的引用。

换句话说,everyString是 a CharSequence,但不是 everyCharSequence是 a String

对接口进行编程

在 Android 中编程,大部分文本值都在 CharSequence 中。

这是为什么?使用 CharSequence over String 有什么好处,主要影响是什么?

通常,对接口进行编程比对具体类进行编程要好。这产生了灵活性,因此我们可以在特定接口的具体实现之间切换而不会破坏其他代码。

在开发供各种程序员在各种情况下使用的API时,编写代码以提供和采用尽可能通用的接口。这使调用程序员可以自由地使用该接口的各种实现,无论哪种实现最适合他们的特定上下文。

例如,查看Java 集合框架。如果您的 API 提供或获取对象的有序集合,请将您的方法声明为 usingList而不是ArrayList,LinkedListList.

当编写一个快速而肮脏的小方法只供您的代码在一个特定位置使用时,而不是编写一个在多个位置使用的 API,您不必费心使用更通用的接口而不是特定的具体接口班级。但即便如此,使用最通用的界面确实会造成伤害。

主要区别是什么,在使用它们时会出现什么问题,

  • 你知道你有String一段文本,完全在内存中,并且是不可变的。
  • 使用 a CharSequence,您不知道具体实现的特定功能可能是什么。

CharSequence对象可能代表大量文本,因此具有内存含义。或者可能是许多单独跟踪的文本块,当您调用时需要将它们拼接在一起toString,因此存在性能问题。该实现甚至可能从远程服务中检索文本,因此具有延迟影响。

并从一个转换到另一个?

您通常不会来回转换。AString 一个CharSequence。如果您的方法声明它需要 a CharSequence,则调用程序员可能会传递一个String对象,或者可能会传递其他东西,例如 aStringBufferStringBuilder。您的方法的代码将简单地使用传递的任何内容,调用任何CharSequence方法。

最接近转换的是如果您的代码收到 aCharSequence并且您知道您需要String. 也许您正在与写入String类而不是写入接口的旧代码进行CharSequence交互。或者您的代码可能会与文本密切合作,例如重复循环或以其他方式分析。在这种情况下,您只想对任何可能的性能造成影响,因此您toString提前打电话。然后使用你所知道的完全在内存中的一段文本继续你的工作。

扭曲的历史

请注意对已接受的 Answer所做的评论。该CharSequence接口被改装到现有的类结构上,因此有一些重要的细微之处(equals()& hashCode())。请注意标记在类/接口上的各种 Java 版本(1、2、4 和 5)——这些年来相当混乱。理想情况下CharSequence,从一开始就已经到位,但生活就是这样。

下面我的类图可以帮助您了解 Java 7/8 中字符串类型的大图。我不确定所有这些是否都存在于 Android 中,但整体上下文可能仍然对您有用。

各种字符串相关的类和接口图

于 2015-07-01T18:30:12.597 回答
39

我相信最好使用 CharSequence。原因是String实现了CharSequence,因此您可以将String传递给CharSequence,但是您不能将CharSequence传递给String,因为CharSequence没有实现String。此外,在 Android 中,该EditText.getText()方法返回一个 Editable,它也实现了 CharSequence,可以很容易地传递给一个,但不容易传递给一个字符串。CharSequence 处理一切!

于 2010-10-27T02:42:34.400 回答
23

通常,使用接口可以让您以最小的附带损害来改变实现。尽管 java.lang.String 非常流行,但在某些情况下可能需要使用另一种实现。通过围绕 CharSequences 而不是 Strings 构建 API,代码提供了这样做的机会。

于 2009-06-26T13:45:59.467 回答
9

在实际的 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()); 
于 2014-11-19T09:36:45.997 回答
8

这几乎可以肯定是性能原因。例如,假设一个解析器通过一个包含字符串的 500k ByteBuffer。

返回字符串内容有 3 种方法:

  1. 在解析时构建一个 String[],一次一个字符。这将花费大量时间。我们可以使用 == 而不是 .equals 来比较缓存的引用。

  2. 在解析时构建一个带有偏移量的 int[],然后在发生 get() 时动态构建 String。每个 String 将是一个新对象,因此不缓存返回值并使用 ==

  3. 在解析时构建一个 CharSequence[]。由于没有存储新数据(除了字节缓冲区的偏移量),解析比#1低得多。在 get 时,我们不需要构建 String,因此 get 性能等于 #1(比 #2 好得多),因为我们只返回对现有对象的引用。

除了使用 CharSequence 获得的处理收益之外,您还可以通过不复制数据来减少内存占用。例如,如果您有一个包含 3 个文本段落的缓冲区,并且想要返回全部 3 个或单个段落,则需要 4 个字符串来表示这一点。使用 CharSequence,您只需要 1 个包含数据的缓冲区,以及 4 个跟踪开始和长度的 CharSequence 实现实例。

于 2011-02-15T15:26:30.337 回答
6

字符序列

ACharSequence是一个接口,而不是一个实际的类。接口只是一个类在实现接口时必须包含的一组规则(方法)。在 Android 中,aCharSequence是各种类型文本字符串的保护伞。以下是一些常见的:

(您可以在此处阅读有关它们之间差异的更多信息。)

如果您有一个CharSequence对象,那么它实际上是实现CharSequence. 例如:

CharSequence myString = "hello";
CharSequence mySpannableStringBuilder = new SpannableStringBuilder();

拥有通用伞类型的好处CharSequence是您可以使用一种方法处理多种类型。例如,如果我有一个将 aCharSequence作为参数的方法,我可以传入 aString或 a SpannableStringBuilder,它会处理其中任何一个。

public int getLength(CharSequence text) {
    return text.length();
}

细绳

你可以说 aString只是 的一种CharSequence。但是,与 不同CharSequence的是,它是一个实际的类,因此您可以从中创建对象。所以你可以这样做:

String myString = new String();

但你不能这样做:

CharSequence myCharSequence = new CharSequence(); // error: 'CharSequence is abstract; cannot be instantiated

由于CharSequence只是String符合的规则列表,您可以这样做:

CharSequence myString = new String();

这意味着任何时候方法要求 a CharSequence,给它 a 就可以了String

String myString = "hello";
getLength(myString); // OK

// ...

public int getLength(CharSequence text) {
    return text.length();
}

然而,事实并非如此。如果该方法接受一个String参数,则不能将通常只知道是 a 的东西传递给它CharSequence,因为它实际上可能是 aSpannableString或其他类型的CharSequence

CharSequence myString = "hello";
getLength(myString); // error

// ...

public int getLength(String text) {
    return text.length();
}
于 2017-11-10T11:45:46.363 回答
0

CharSequence是一个接口并String实现它。您可以实例化 aString但您不能这样做,CharSequence因为它是一个接口。CharSequence您可以在官方 Java 网站中找到其他实现。

于 2017-08-29T04:39:43.430 回答
-5

CharSequence 是一个可读的 char 值序列,它实现了 String。它有4种方法

  1. charAt(int 索引)
  2. 长度()
  3. 子序列(int开始,int结束)
  4. toString()

请参考文档CharSequence 文档

于 2016-09-28T16:57:51.273 回答