java字符串问题

Python011

java字符串问题,第1张

1.

首先String不属于8种基本数据类型,String是一个对象。

因为对象的默认值是null,所以String的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性。

2.

new String()和new String(“”)都是申明一个新的空字符,是空串不是null;

3.

String str=”kvill”;

String

str=new String (“kvill”)的区别:

在这里,我们不谈堆,也不谈栈,只先简单引入常量池这个简单的概念。

常量池(constant

pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。

看例1:

String

s0=”kvill”

String

s1=”kvill”

String

s2=”kv” + “ill”

System.out.println(

s0==s1 )

System.out.println(

s0==s2 )

结果为:

true

true

首先,我们要知道Java会确保一个字符串常量只有一个拷贝。

因为例子中的s0和s1中的”kvill”都是字符串常量,它们在编译期就被确定了,所以s0==s1为true;而”kv”和”ill”也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中

”kvill”的一个引用。

所以我们得出s0==s1==s2

用new

String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。

看例2:

String

s0=”kvill”

String

s1=new String(”kvill”)

String

s2=”kv” + new String(“ill”)

System.out.println(

s0==s1 )

System.out.println(

s0==s2 )

System.out.println(

s1==s2 )

结果为:

false

false

false

例2中s0还是常量池中”kvill”的应用,s1因为无法在编译期确定,所以是运行时创建的新对象”kvill”的引用,s2因为有后半部分new

String(“ill”)所以也无法在编译期确定,所以也是一个新创建对象”kvill”的应用明白了这些也就知道为何得出此结果了。

4.

String.intern():

再补充介绍一点:存在于.class文件中的常量池,在运行期被JVM装载,并且可以扩充。String的intern()方法就是扩充常量池的一个方法;当一个String实例str调用intern()方法时,Java查找常量池中是否有相同Unicode的字符串常量,如果有,则返回其的引用,如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引用;看例3就清楚了

例3:

String

s0= “kvill”

String

s1=new String(”kvill”)

String

s2=new String(“kvill”)

System.out.println(

s0==s1 )

System.out.println(

“**********” )

s1.intern()

s2=s2.intern()

//把常量池中“kvill”的引用赋给s2

System.out.println(

s0==s1)

System.out.println(

s0==s1.intern() )

System.out.println(

s0==s2 )

结果为:

false

**********

false

//虽然执行了s1.intern(),但它的返回值没有赋给s1

true

//说明s1.intern()返回的是常量池中”kvill”的引用

true

最后我再破除一个错误的理解:

有人说,“使用String.intern()方法则可以将一个String类的保存到一个全局String表中,如果具有相同值的Unicode字符串已经在这个表中,那么该方法返回表中已有字符串的地址,如果在表中没有相同值的字符串,则将自己的地址注册到表中“如果我把他说的这个全局的

String表理解为常量池的话,他的最后一句话,“如果在表中没有相同值的字符串,则将自己的地址注册到表中”是错的:

看例4:

String

s1=new String("kvill")

String

s2=s1.intern()

System.out.println(

s1==s1.intern() )

System.out.println(

s1+" "+s2 )

System.out.println(

s2==s1.intern() )

结果:

false

kvill

kvill

true

在这个类中我们没有声名一个”kvill”常量,所以常量池中一开始是没有”kvill”的,当我们调用s1.intern()后就在常量池中新添加了一个”kvill”常量,原来的不在常量池中的”kvill”仍然存在,也就不是“将自己的地址注册到常量池中”了。

s1==s1.intern()为false说明原来的“kvill”仍然存在;

s2现在为常量池中“kvill”的地址,所以有s2==s1.intern()为true。

5.

关于equals()和==:

这个对于String简单来说就是比较两字符串的Unicode序列是否相当,如果相等返回true而==是比较两字符串的地址是否相同,也就是是否是同一个字符串的引用。

6.

关于String是不可变的

这一说又要说很多,大家只要知道String的实例一旦生成就不会再改变了,比如说:String

str=”kv”+”ill”+” “+”ans”

就是有4个字符串常量,首先”kv”和”ill”生成了”kvill”存在内存中,然后”kvill”又和”

“ 生成 ”kvill “存在内存中,最后又和生成了”kvill

ans”并把这个字符串的地址赋给了str,就是因为String的“不可变”产生了很多临时变量,这也就是为什么建议用StringBuffer的原因了,因为StringBuffer是可改变的。

(java)如何获取字符串的字节数!, java怎样获取字符串的字节数

字符串是可以转变成字节数组,然后统计一下字节数组的长度即可,参考如下代码:

Java语言中,中文字符所占的字节数取决于字符的编码方式,一般情况下,采用ISO8859-1编码方式时,一个中文字符与一个英文字符一样只占1个字节;采用GB2312或GBK编码方式时,一个中文字符占2个字节;而采用UTF-8编码方式时,一个中文字符会占3个字节。

public static void main(String []args) throws UnsupportedEncodingException {

运行结果:2

System.out.println("测试".getBytes("ISO8859-1").length)

运行结果:4

System.out.println("测试".getBytes("GB2312").length)

运行结果:4

System.out.println("测试".getBytes("GBK").length)

运行结果:6

System.out.println("测试".getBytes("UTF-8").length)

}

c# 获取字符串的字节数

C#截取字符串字节数 代码如下:

public int bytelenght(string str)

{

byte[] bytestr = System.Text.Encoding.Unicode.GetBytes(str)

int j = 0

for (int i = 0i <bytestr.GetLength(0)i++)

{

if (i % 2 == 0)

{

j++

}

else

{

if (bytestr[i] >0)

{

j++

}

}

}

return j

}

谢谢采纳

c++ 怎样获取一串字符串的字符数,不是字节数

定义一个字符数组,然后根据字符长度循环得到字符

比如char ch[20]

这个20可以用字符实际长度getlength()获取

然后再循环获取字符

ch[i]

c#求字符串的字节数

其实用不着那么复杂计算的。注意:C#中string.Length只是计算字符串“字符”的个数,不计算字节;但是汉字两个字节+数字(英文字符)一个字节,才是6个,简单的代码如下: byte[] bytes = Encoding.Default.GetBytes("1243我")Default(根据自己究竟是汉字还是数字等,自动合理分配内存所需要的字节空间)

Console.WriteLine(bytes.Length)

C#如何获得存放字符串的字节数组?

byte[] System.Text.Encoding.Default.GetBytes(string s)

如何计算一个Unicode字符串的字节数

你就是一个byte一个byte读取的吧?一个汉字两个byte(不含surrogate情况),文件中存两个byte,你从文件中读取2个byte,就是这样 查看原帖>>

java下字符串和字节数组如何转换?

strRead = String.copyValueOf(strRead.toCharArray(), 0, byBuffer.length])2、字符串转换成字节数组 byte[] byBuffer = new byte[200]byBuffer= strInput.getBytes()注意:如果字符串里面含有中文,要特别注意,在android系统下,默认是UTF8编码,一个中文字符相当于3个字节,只有gb2312下一个中文相当于2字节。

12.4.4 String 和 StringBuffer 类

这里总结一下同时适用于 String 和 StringBuffer 的方法,以便对它们相互间

的沟通方式有一个印象。这些表格并未把每个单独的方法都包括进去,而是包含

了与本次讨论有重要关系的方法。那些已被覆盖的方法用单独一行总结。

首先总结 String 类的各种方法:

方法 自变量,覆盖 用途

构建器 已被覆盖:默认,String,StringBuffer,char 数组,byte 数组 创建

String 对象

length() 无 String 中的字符数量

charAt() int Index 位于 String 内某个位置的 char

getChars(),getBytes 开始复制的起点和终点,要向其中复制内容的数组,对

目标数组的一个索引 将 char 或 byte 复制到外部数组内部

toCharArray() 无 产生一个 char[],其中包含了 String 内部的字符

equals(),equalsIgnoreCase() 用于对比的一个 String 对两个字串的内容进行

等价性检查

compareTo() 用于对比的一个 String 结果为负、零或正,具体取决于 String

和自变量的字典顺序。注意大写和小写不是相等的!

regionMatches() 这个 String 以及其他 String 的位置偏移,以及要比较的区域

长度。覆盖加入了“忽略大小写”的特性 一个布尔结果,指出要对比的区域是

否相同

startsWith() 可能以它开头的 String。覆盖在自变量里加入了偏移 一个布尔

结果,指出 String 是否以那个自变量开头

endsWith() 可能是这个 String 后缀的一个 String 一个布尔结果,指出自变量

是不是一个后缀

indexOf(),lastIndexOf() 已覆盖:char,char 和起始索引,String,String 和起

始索引 若自变量未在这个 String 里找到,则返回-1否则返回自变量开始处的

位置索引。lastIndexOf()可从终点开始回溯搜索

substring() 已覆盖:起始索引,起始索引和结束索引 返回一个新的 String

对象,其中包含了指定的字符子集

concat() 想连结的 String 返回一个新 String 对象,其中包含了原始 String 的

字符,并在后面加上由自变量提供的字符

relpace() 要查找的老字符,要用它替换的新字符 返回一个新 String 对象,

其中已完成了替换工作。若没有找到相符的搜索项,就沿用老字串

toLowerCase(),toUpperCase() 无 返回一个新 String 对象,其中所有字符的大

小写形式都进行了统一。若不必修改,则沿用老字串

trim() 无 返回一个新的 String 对象,头尾空白均已删除。若毋需改动,则沿

用老字串

valueOf() 已覆盖:object,char[],char[]和偏移以及计数,boolean,char,int,

long,float,double 返回一个 String,其中包含自变量的一个字符表现形式

Intern() 无 为每个独一无二的字符顺序都产生一个(而且只有一个)String

句柄

可以看到,一旦有必要改变原来的内容,每个 String 方法都小心地返回了一

个新的 String 对象。另外要注意的一个问题是,若内容不需要改变,则方法只返

回指向原来那个 String 的一个句柄。这样做可以节省存储空间和系统开销。

下面列出有关 StringBuffer(字串缓冲)类的方法:

方法 自变量,覆盖 用途

构建器 已覆盖:默认,要创建的缓冲区长度,要根据它创建的 String 新建

一个 StringBuffer 对象

toString() 无 根据这个 StringBuffer 创建一个 String

length() 无 StringBuffer 中的字符数量

capacity() 无 返回目前分配的空间大小

ensureCapacity() 用于表示希望容量的一个整数 使 StringBuffer 容纳至少希

望的空间大小

setLength() 用于指示缓冲区内字串新长度的一个整数 缩短或扩充前一个字

符串。如果是扩充,则用 null 值填充空隙

charAt() 表示目标元素所在位置的一个整数 返回位于缓冲区指定位置处的

char

setCharAt() 代表目标元素位置的一个整数以及元素的一个新 char 值 修改指

定位置处的值

getChars() 复制的起点和终点,要在其中复制的数组以及目标数组的一个索

引 将 char 复制到一个外部数组。和 String 不同,这里没有 getBytes()可供使用

append() 已覆盖:Object,String,char[],特定偏移和长度的 char[],boolean,

char,int,long,float,double 将自变量转换成一个字串,并将其追加到当前缓

冲区的末尾。若有必要,同时增大缓冲区的长度

insert() 已覆盖,第一个自变量代表开始插入的位置:Object,String,char[],

boolean,char,int,long,float,double 第二个自变量转换成一个字串,并插入

当前缓冲区。插入位置在偏移区域的起点处。若有必要,同时会增大缓冲区的长

reverse() 无 反转缓冲内的字符顺序

最常用的一个方法是 append()。在计算包含了+和+=运算符的 String 表达式

时,编译器便会用到这个方法。insert()方法采用类似的形式。这两个方法都能对

缓冲区进行重要的操作,不需要另建新对象。

12.4.5 字串的特殊性

现在,大家已知道 String 类并非仅仅是 Java 提供的另一个类。String 里含有

大量特殊的类。通过编译器和特殊的覆盖或过载运算符+和+=,可将引号字符串

转换成一个 String。在本章中,大家已见识了剩下的一种特殊情况:用同志

StringBuffer 精心构造的“不可变”能力,以及编译器中出现的一些有趣现象。