Java中的CharSequence VS String?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1049228/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
CharSequence VS String in Java?
提问by e-satis
Programming in Android, most of the text values are expected in CharSequence
.
在 Android 中编程,大多数文本值都在CharSequence
.
Why is that? What is the benefit, and what are the main impacts of using CharSequence
over String
?
这是为什么?有什么好处,使用CharSequence
over的主要影响是String
什么?
What are the main differences, and what issues are expected, while using them, and converting from one to another?
在使用它们以及从一种转换到另一种时,主要区别是什么,预期会出现哪些问题?
采纳答案by Zarkonnen
Strings are CharSequences, so you can just use Strings and not worry. Android is merely trying to be helpful by allowing you to also specify other CharSequence objects, like StringBuffers.
字符串是 CharSequences,所以你可以只使用字符串而不用担心。Android 只是试图通过允许您还指定其他 CharSequence 对象(如 StringBuffers)来提供帮助。
回答by Itay Maman
In general using an interface allows you to vary the implementation with minimal collateral damage. Although java.lang.String are super popular it may be possible that in certain contexts one may want to use another implementation. By building the API around CharSequences rather than Strings the code gives one the opportunity to do that.
通常,使用接口允许您以最小的附带损害来改变实现。尽管 java.lang.String 非常流行,但在某些情况下,人们可能想要使用另一种实现。通过围绕 CharSequences 而不是 Strings 构建 API,代码为人们提供了这样做的机会。
回答by Sham
I believe it is best to use CharSequence. The reason is that String implements CharSequence, therefore you can pass a String into a CharSequence, HOWEVER you cannot pass a CharSequence into a String, as CharSequence doesn't not implement String. ALSO, in Android the EditText.getText()
method returns an Editable, which also implements CharSequence and can be passed easily into one, while not easily into a String. CharSequence handles all!
我相信最好使用 CharSequence。原因是 String 实现了 CharSequence,因此您可以将 String 传递到 CharSequence,但是您不能将 CharSequence 传递到 String,因为 CharSequence 没有实现 String。此外,在 Android 中,该EditText.getText()
方法返回一个 Editable,它也实现了 CharSequence 并且可以轻松地传递给一个,而不容易传递给一个字符串。CharSequence 处理所有!
回答by Phil Lello
This is almost certainly performance reasons. For example, imagine a parser that goes through a 500k ByteBuffer containing strings.
这几乎可以肯定是性能原因。例如,假设一个解析器通过一个包含字符串的 500k ByteBuffer。
There are 3 approaches to returning the string content:
有 3 种方法可以返回字符串内容:
Build a String[] at parse time, one character at a time. This will take a noticeable amount of time. We can use == instead of .equals to compare cached references.
Build an int[] with offsets at parse time, then dynamically build String when a get() happens. Each String will be a new object, so no caching returned values and using ==
Build a CharSequence[] at parse time. Since no new data is stored (other than offsets into the byte buffer), the parsing is much lower that #1. At get time, we don't need to build a String, so get performance is equal to #1 (much better than #2), as we're only returning a reference to an existing object.
在解析时构建一个 String[],一次一个字符。这将需要相当长的时间。我们可以使用 == 而不是 .equals 来比较缓存的引用。
在解析时构建一个带有偏移量的 int[],然后在 get() 发生时动态构建 String。每个 String 将是一个新对象,因此不会缓存返回值并使用 ==
在解析时构建一个 CharSequence[]。由于没有存储新数据(除了字节缓冲区的偏移量),解析比#1 低得多。在获取时,我们不需要构建字符串,因此获取性能等于 #1(比 #2 好得多),因为我们只返回对现有对象的引用。
In addition to the processing gains you get using CharSequence, you also reduce the memory footprint by not duplicating data. For example, if you have a buffer containing 3 paragraphs of text, and want to return either all 3 or a single paragraph, you need 4 Strings to represent this. Using CharSequence you only need 1 buffer with the data, and 4 instances of a CharSequence implementation that tracks the start and length.
除了使用 CharSequence 获得的处理收益之外,您还可以通过不复制数据来减少内存占用。例如,如果您有一个包含 3 个文本段落的缓冲区,并且想要返回全部 3 个或单个段落,则需要 4 个字符串来表示它。使用 CharSequence 您只需要 1 个包含数据的缓冲区,以及跟踪开始和长度的 CharSequence 实现的 4 个实例。
回答by Crypth
An issue that DO arise in practical Android code is that comparing them with CharSequence.equals is valid but does not necessarily work as intended.
在实际的 Android 代码中确实出现的一个问题是,将它们与 CharSequence.equals 进行比较是有效的,但不一定按预期工作。
EditText t = (EditText )getView(R.id.myEditText); // Contains "OK"
Boolean isFalse = t.getText().equals("OK"); // will always return false.
Comparison should be made by
比较应该由
("OK").contentEquals(t.GetText());
回答by Basil Bourque
CharSequence
= interface
String
= concrete implementation
CharSequence
= 接口
String
= 具体实现
CharSequence
is an interface.- Several classes implementthis interface.
String
is one such class, a concrete implementation ofCharSequence
.
CharSequence
是一个接口。- 有几个类实现了这个接口。
String
就是一个这样的类,是CharSequence
.
You said:
你说:
converting from one to another
从一种转换到另一种
There is no converting from String
.
没有从String
.
- Every
String
object isaCharSequence
. - Every
CharSequence
can produce aString
. CallCharSequence::toString
. If theCharSequence
happens to be aString
, then the method returns a reference to its own object.
- 每个
String
对象都是一个CharSequence
. - 每个都
CharSequence
可以产生一个String
. 打电话CharSequence::toString
。如果CharSequence
恰好是 aString
,则该方法返回对其自身对象的引用。
In other words, every String
is a CharSequence
, but not every CharSequence
is a String
.
换句话说, everyString
是 a CharSequence
,但不是 everyCharSequence
是 a String
。
Programming to an interface
编程到接口
Programming in Android, most of the text values are expected in CharSequence.
Why is that? What is the benefit, and what are the main impacts of using CharSequence over String?
在 Android 中编程,大部分文本值都在 CharSequence 中。
这是为什么?有什么好处,使用 CharSequence 而不是 String 的主要影响是什么?
Generally, programming to an interface is better than programming to concrete classes. This yields flexibility, so we can switch between concrete implementations of a particular interface without breaking other code.
通常,对接口进行编程比对具体类进行编程要好。这产生了灵活性,因此我们可以在不破坏其他代码的情况下在特定接口的具体实现之间切换。
When developing an APIto be used by various programmers in various situations, write your code to give and take the most general interfaces possible. This gives the calling programmer the freedom to use various implementations of that interface, whichever implementation is best for their particular context.
在开发供各种程序员在各种情况下使用的API 时,请编写代码以提供和采用最通用的接口。这使调用程序员可以自由地使用该接口的各种实现,无论哪种实现最适合其特定上下文。
For example, look at the Java Collections Framework. If your API gives or takes an ordered collection of objects, declare your methods as using List
rather than ArrayList
, LinkedList
, or any other 3rd-party implementation of List
.
例如,查看Java 集合框架。如果您的API给或采取对象的有序集合,如使用声明你的方法List
,而不是ArrayList
,LinkedList
或任何其他第三方实现List
。
When writing a quick-and-dirty little method to be used only by your code in one specific place, as opposed to writing an API to be used in multiple places, you need not bother with using the more general interface rather than a specific concrete class. But even then, it does to hurt to use the most general interface you can.
当编写一个只在一个特定地方由你的代码使用的快速而肮脏的小方法时,而不是编写一个在多个地方使用的 API,你不需要费心使用更通用的接口而不是特定的具体班级。但即便如此,尽可能使用最通用的界面也会造成伤害。
What are the main differences, and what issues are expected, while using them,
主要区别是什么,在使用它们时会出现什么问题,
- With a
String
you know you have a single piece of text, entirely in memory, and is immutable. - With a
CharSequence
, you do not know what the particular features of the concrete implementation might be.
- 有了 a
String
你知道你有一段文本,完全在内存中,并且是不可变的。 - 使用
CharSequence
,您不知道具体实现的特定功能可能是什么。
The CharSequence
object might represent an enormous chunk of text, and therefore has memory implications. Or may be many chunks of text tracked separately that will need to be stitched together when you call toString
, and therefore has performance issues. The implementation may even be retrieving text from a remote service, and therefore has latency implications.
该CharSequence
对象可能代表大量文本,因此具有内存影响。或者可能是许多单独跟踪的文本块,在调用 时需要将它们拼接在一起toString
,因此存在性能问题。该实现甚至可能从远程服务检索文本,因此具有延迟影响。
and converting from one to another?
并从一种转换为另一种?
You generally won't be converting back and forth. A String
isa CharSequence
. If your method declares that it takes a CharSequence
, the calling programmer may pass a String
object, or may pass something else such as a StringBuffer
or StringBuilder
. Your method's code will simply use whatever is passed, calling any of the CharSequence
methods.
您通常不会来回转换。AString
是一个CharSequence
。如果您的方法声明它需要 a CharSequence
,则调用程序员可能会传递一个String
对象,或者可能会传递其他内容,例如 aStringBuffer
或StringBuilder
。您方法的代码将简单地使用传递的任何内容,调用任何CharSequence
方法。
The closest you would get to converting is if your code receives a CharSequence
and you know you need a String
. Perhaps your are interfacing with old code written to String
class rather than written to the CharSequence
interface. Or perhaps your code will work intensively with the text, such as looping repeatedly or otherwise analyzing. In that case, you want to take any possible performance hit only once, so you call toString
up front. Then proceed with your work using what you know to be a single piece of text entirely in memory.
最接近转换的是,如果您的代码收到一个CharSequence
并且您知道您需要一个String
. 也许您正在与写入String
类而不是写入接口的旧代码CharSequence
交互。或者,您的代码可能会大量处理文本,例如重复循环或以其他方式进行分析。在这种情况下,您只想对任何可能的性能造成影响,因此您需要toString
提前调用。然后使用您所知道的完全在内存中的一段文本继续您的工作。
Twisted history
扭曲的历史
Note the comments made on the accepted Answer. The CharSequence
interface was retrofitted onto existing class structures, so there are some important subtleties (equals()
& hashCode()
). Notice the various versions of Java (1, 2, 4 & 5) tagged on the classes/interfaces—quite a bit of churn over the years. Ideally CharSequence
would have been in place from the beginning, but such is life.
请注意对已接受的答案所做的评论。所述CharSequence
接口被改装到现有的类结构,所以有一些重要的细微之处(equals()
&hashCode()
)。请注意在类/接口上标记的各种 Java 版本(1、2、4 和 5)——这些年来有相当多的变动。理想情况下CharSequence
,从一开始就已经到位,但这就是生活。
My class diagram below may help you see the big picture of string types in Java 7/8. I'm not sure if all of these are present in Android, but the overall context may still prove useful to you.
我下面的类图可以帮助您了解 Java 7/8 中字符串类型的大图。我不确定 Android 中是否存在所有这些内容,但总体上下文可能仍然对您有用。
回答by Srinivas Thammanaboina
CharSequence is a readable sequence of char values which implements String. it has 4 methods
CharSequence 是一个可读的 char 值序列,它实现了 String。它有4种方法
- charAt(int index)
- length()
- subSequence(int start, int end)
- toString()
- charAt(int 索引)
- 长度()
- 子序列(int 开始,int 结束)
- toString()
Please refer documentation CharSequence documentation
请参考文档CharSequence 文档
回答by Xiaogang
CharSequence
is an interface and String
implements it. You can instantiate a String
but you could not do that for CharSequence
since it is an interface. You can find other implementations in CharSequence
in the official Java website.
CharSequence
是一个接口并String
实现它。你可以实例化 aString
但你不能这样做,CharSequence
因为它是一个接口。您可以CharSequence
在官方 Java 网站中找到其他实现。
回答by Suragch
CharSequence
字符序列
A CharSequence
is an interface, not an actual class. An interface is just a set of rules (methods) that a class must contain if it implements the interface. In Android a CharSequence
is an umbrella for various types of text strings. Here are some of the common ones:
ACharSequence
是一个接口,而不是一个实际的类。接口只是类实现接口时必须包含的一组规则(方法)。在 Android 中,aCharSequence
是各种类型文本字符串的保护伞。以下是一些常见的:
String
(immutable text with no styling spans)StringBuilder
(mutable text with no styling spans)SpannableString
(immutable text with styling spans)SpannableStringBuilder
(mutable text with styling spans)
String
(没有样式跨度的不可变文本)StringBuilder
(没有样式跨度的可变文本)SpannableString
(具有样式跨度的不可变文本)SpannableStringBuilder
(具有样式跨度的可变文本)
(You can read more about the differences between these here.)
(您可以在此处阅读有关这些差异的更多信息。)
If you have a CharSequence
object, then it is actually an object of one of the classes that implement CharSequence
. For example:
如果您有一个CharSequence
对象,那么它实际上是实现CharSequence
. 例如:
CharSequence myString = "hello";
CharSequence mySpannableStringBuilder = new SpannableStringBuilder();
The benefit of having a general umbrella type like CharSequence
is that you can handle multiple types with a single method. For example, if I have a method that takes a CharSequence
as a parameter, I could pass in a String
or a SpannableStringBuilder
and it would handle either one.
拥有通用伞型类型的好处CharSequence
是您可以使用单个方法处理多种类型。例如,如果我有一个将 aCharSequence
作为参数的方法,我可以传入 aString
或 aSpannableStringBuilder
并且它会处理任何一个。
public int getLength(CharSequence text) {
return text.length();
}
String
细绳
You could say that a String
is just one kind of CharSequence
. However, unlike CharSequence
, it is an actual class, so you can make objects from it. So you could do this:
你可以说 aString
只是一种CharSequence
。但是,与 不同的是CharSequence
,它是一个实际的类,因此您可以从中创建对象。所以你可以这样做:
String myString = new String();
but you can't do this:
但你不能这样做:
CharSequence myCharSequence = new CharSequence(); // error: 'CharSequence is abstract; cannot be instantiated
Since CharSequence
is just a list of rules that String
conforms to, you could do this:
由于CharSequence
只是String
符合规则的列表,您可以这样做:
CharSequence myString = new String();
That means that any time a method asks for a CharSequence
, it is fine to give it a String
.
这意味着任何时候一个方法要求 a CharSequence
,就可以给它 a String
。
String myString = "hello";
getLength(myString); // OK
// ...
public int getLength(CharSequence text) {
return text.length();
}
However, the opposite is not true. If the method takes a String
parameter, you can't pass it something that is only generally known to be a CharSequence
, because it might actually be a SpannableString
or some other kind of CharSequence
.
然而,事实并非如此。如果该方法接受一个String
参数,则不能向它传递通常只知道是 a 的东西CharSequence
,因为它实际上可能是 aSpannableString
或其他类型的CharSequence
。
CharSequence myString = "hello";
getLength(myString); // error
// ...
public int getLength(String text) {
return text.length();
}