char值序列是什么Java_Java中的CharSequence VS String?

在Android中编程时,大多数文本值应在CharSequence中。

这是为什么? 使用CharSequence而不是String有什么好处?

主要区别是什么?在使用它们并将它们从一个转换为另一个时会遇到什么问题?

在Java中CharSequence和String的确切区别时可以找到更好的答案

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

除非Android在回调中向我传递CharSequence,并且我需要一个String-调用charSeq.toString()。

但是请记住来自CharSequence javadoc的警告:此接口不会完善equals和hashCode方法的常规协定。因此,比较两个实现CharSequence的对象的结果通常是不确定的。每个对象都可以由不同的类实现,并且不能保证每个类都能够测试其实例与另一个实例的相等性。因此,将任意CharSequence实例用作集合中的元素或用作映射中的键是不合适的。

@TrevorRobinson,那不是设计错误吗?

@Pacerier:我认为这更多是实际的限制。 CharSequence是JDK 1.4的一种改进,为包含字符序列的对象引入了有限用途的通用接口。这些对象中的某些包含其他状态,因此将Object.equals定义为"包含相同的字符序列"可能没有意义。例如,NIO CharBuffer仅将其position和limit之间的字符公开为CharSequence,尽管可能保留许多其他字符。

@TrevorRobinson,因此设计错误首先是在Object上具有equals / hashCode。

@Pacerier:恕我直言,Object或CharSequence中都没有设计错误,不需要接口就可以在实现之间提供相等的完整性。不需要两个Collection来提供Collection接口之间的相等性,但是如果愿意的话,它们可以。 IMHO CharSequence应该限于输入,而对于返回类型则应较少使用。

@Pacerier,是的。

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

另外,请注意对已接受答案的评论。 CharSequence接口被改型到现有的类结构上,因此存在一些重要的细微之处(equals()和hashCode())。请注意在类/接口上标记的Java的各种版本(1、2、4和5),这些年来有些翻腾。理想情况下,CharSequence从一开始就应该存在,但这就是生活。

739859b99987f807e7b83ea823118f39.png

您是否自己制作了此图?想知道是否有针对不同数据结构的这些图的目录。

@ user171943由我编写,使用OmniGroup的OmniGraffle应用程序手工制作。

我相信最好使用CharSequence。原因是String实现了CharSequence,因此您可以将String传递给CharSequence,但是您不能将CharSequence传递给String,因为CharSequence不实现String。另外,在Android中,EditText.getText()方法返回一个Editable,该方法也实现了CharSequence,可以轻松地传递给一个,而不容易传递给String。 CharSequence处理所有操作!

你可以做charSequence.toString()

@jorge:除非序列可变(或者出于任何原因需要复制字符以便生成不可变的字符串),否则效率相对较低。

很好的解释..!

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

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

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

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

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

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

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

参考PLZ。听起来像是随机猜测发生了什么。我也觉得你的论点无效。首先可能只是将500k字节缓冲区存储为字符串,然后只返回子字符串,这非常疯狂,而且更为常见。

@kritzikratzi-从JDK7开始,String上的子字符串不再共享底层数组,并且不是"疯狂快速"。子字符串的长度需要O(N)时间,并且每次调用它都会生成基础字符的副本(因此会产生大量垃圾)。

@kritzikratzi我相信更改的原因是,如果不进行复制,则将在所有子字符串的生命周期内保留原始String。鉴于子字符串通常只是原始字符串的一小部分,并且可以无限期地使用,具体取决于它们的使用方式,如果子字符串的使用时间比原始字符串长得多,这通常会导致更多的垃圾。一个有趣的替代方法可能是根据子字符串与父字符串大小的比率确定是否要复制,但是您必须为此滚动自己的CharSequence实现。

也许我已经错了重点,但是这个答案是胡说八道。 CharSequence是接口–根据定义,它没有您讨论的实现细节,因为它没有自己的实现。 String是实现CharSequence接口的几个具体类之一。所以String是CharSequence。您可以比较String与StringBuffer与StringBuilder的性能详细信息,但不能比较CharSequence。编写"使用CharSequence获得的处理收益"是没有意义的。

在实际的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是一个接口,而不是实际的类。接口只是类在实现接口时必须包含的一组规则(方法)。在Android中,CharSequence是各种类型的文本字符串的保护伞。这是一些常见的:

String(不带样式范围的不可变文本)

StringBuilder(无样式跨度的可变文本)

SpannableString(具有样式范围的不可变文本)

SpannableStringBuilder(具有样式范围的可变文本)

(您可以在此处详细了解它们之间的区别。)

如果您有一个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或某种其他类型的CharSequence。

CharSequence myString ="hello";

getLength(myString); // error

// ...

public int getLength(String text) {

return text.length();

}

很好的答案! 谢谢!

CharSequence是一个接口,String实现它。您可以实例化String,但是由于CharSequence是接口,因此无法对其进行实例化。您可以在Java官方网站的CharSequence中找到其他实现。

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

charAt(int索引)

长度()

subSequence(整数开始,整数结束)

toString()

请参阅文档CharSequence文档

CharSequence不实现String。 相反,这是正确的。

请删除这个废话答案

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值