最近发现自己有个习惯,特别喜欢把东西放在string中,然后慢慢的去使用string,然后?然后发现自己对string这玩意熟知度实在太低了,想想还是得好好复习下,所以写下这个复习博客
1. String str=new String("abc")和String str="abc"的字符串“abc”都是存放在堆中,而不是存在
栈中。
2. 其实在在java中有一个“字符数据池”的内存管理机制。
3. String str="abc",执行这句话时,会先去“字符数据池”搜索时候有“abc”这个字符串,如果有
,则将字符串的首地址赋值给str,如果没有,生成一个新的字符串“abc”并且将首地址赋值给str;
4. String str=new String("abc"),执行这句话时,不会考虑时候已经存在了“abc”这个字符串,而
是直接生成一个新的字符串“abc”并将首地址赋值给str,注意“abc”并不放在“字符数据池”中;
5. 由以上分析可知,String str="abc"和效率要高于String str=new String("abc"),因为如果有重复
的字符串时,第一种方式可以节省空间。
6. 下面举例说明一下,好好看看结果,仔细分析原因,上面已经说明的很清楚了:
public class Test{
public static void main(String args[]){
String s1=new String("abc");//直接在堆中生成新的“abc”
String s2=new String("abc");//直接在堆中生成新的“abc”
String s3="abc";//先去“字符数据池”搜索时候有“abc”这个字符串,如果有,则
将字符串的首地址赋值给s3,如果没有,则在“字符数据池”中生成一个新的字符串“abc”并且将首地
址赋值给s3;
String s4="abc";//去“字符数据池”搜索时发现了上一步生成的“abc”这个字符串
,把该字符串首地址赋值给s4,这时其实s3和s4指向同一个字符数据池中的“abc”
System.out.println(s1==s2);
System.out.println(s1==s3);
System.out.println(s2==s3);
System.out.println(s3==s4);
}
}
结果:
false
fasle
false
true
另外:例如:
String str1=”java”; //指向字符串池
String str2=”blog”; //指向字符串池
String s=str1+str2; //s是指向堆中值为"javablog"的对象,+运算符会在堆中建立来两个String对象,这两个对象的值分别是"java" "blog". 也就是说从字符串池中复制这两个值,然后在堆中创建两个对象,然后再建立对象s,然后将"javablog"的堆地址赋给s. 这句共创建了?个String 对象!
System.out.println(s==”javablog”); //结果是false。
Jvm确实对型如String str1=”java”;的String对象放在常量池里,但是它是在编译时那么做的,而String s=str1+str2;是在运行时刻才能知道,也就是说str1+str2是在堆里创建的,所以结果为false了。
如果改成一下两种方式:
String s="java" + "blog"; //直接将"javablog"放入字符串池中,System.out.println(s==”javablog”); 的结果为true, 这个句子创建了?个String对象
String s=str1+ "blog"; //不放入字符串池,而是在堆中分配,System.out.println(s==”javablog”); 的结果为False, 这个句子创建了?个String对象
总结
综上所述,创建字符串有两种方式:两种内存区域(pool,heap)
1," " 引号创建的字符串在字符串池中
2,new,new创建字符串时首先查看池中是否有相同值的字符串,如果有,则拷贝一份到堆中,然后返回堆中的地址;如果池中没有,则在堆中创建一份,然后返回堆中的地址(注意,此时不需要从堆中复制到池中,否则,将使得堆中的字符串永远是池中的子集,导致浪费池的空间)!
另外,对字符串进行赋值时,如果右操作数含有一个或一个以上的字符串引用时,则在堆中再建立一个字符串对象,返回引用;如String s=str1+ "blog";
---------------------------------------------------------------------------------------------
以上这段是在别的博客上看到的,本来想概述一下,但是这些大家都知道的,而且自己文笔也不好,就直接复制粘贴过来
接下来还是讲讲对string的操作
看看jdk(1.6),直接跳过构造方法,来到方法摘要中
char | charAt(int index) 返回指定索引处的 char 值。 |
int | codePointAt(int index) 返回指定索引处的字符(Unicode 代码点)。 |
int | codePointBefore(int index) 返回指定索引之前的字符(Unicode 代码点)。 |
int | codePointCount(int beginIndex, int endIndex) 返回此 String 的指定文本范围中的 Unicode 代码点数。 |
int | compareTo(String anotherString) 按字典顺序比较两个字符串。 |
int | compareToIgnoreCase(String str) 按字典顺序比较两个字符串,不考虑大小写。 |
String | concat(String str) 将指定字符串连接到此字符串的结尾。 |
boolean | contains(CharSequence s) 当且仅当此字符串包含指定的 char 值序列时,返回 true。 |
boolean | contentEquals(CharSequence cs) 将此字符串与指定的 CharSequence 比较。 |
boolean | contentEquals(StringBuffer sb) 将此字符串与指定的 StringBuffer 比较。 |
static String | copyValueOf(char[] data) 返回指定数组中表示该字符序列的 String。 |
static String | copyValueOf(char[] data, int offset, int count) 返回指定数组中表示该字符序列的 String。 |
boolean | endsWith(String suffix) 测试此字符串是否以指定的后缀结束。 |
boolean | equals(Object anObject) 将此字符串与指定的对象比较。 |
boolean | equalsIgnoreCase(String anotherString) 将此 String 与另一个 String 比较,不考虑大小写。 |
static String | format(Locale l,String format,Object... args) 使用指定的语言环境、格式字符串和参数返回一个格式化字符串。 |
static String | format(String format,Object... args) 使用指定的格式字符串和参数返回一个格式化字符串。 |
byte[] | getBytes() 使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 |
byte[] | getBytes(Charset charset) 使用给定的 charset 将此 String 编码到 byte 序列,并将结果存储到新的 byte 数组。 |
void | getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin) 已过时。 该方法无法将字符正确转换为字节。从 JDK 1.1 起,完成该转换的首选方法是通过 getBytes() 方法,该方法使用平台的默认字符集。 |
byte[] | getBytes(String charsetName) 使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 |
void | getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) 将字符从此字符串复制到目标字符数组。 |
int | hashCode() 返回此字符串的哈希码。 |
int | indexOf(int ch) 返回指定字符在此字符串中第一次出现处的索引。 |
int | indexOf(int ch, int fromIndex) 返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索。 |
int | indexOf(String str) 返回指定子字符串在此字符串中第一次出现处的索引。 |
int | indexOf(String str, int fromIndex) 返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。 |
String | intern() 返回字符串对象的规范化表示形式。 |
boolean | isEmpty() 当且仅当 length() 为0 时返回 true。 |
int | lastIndexOf(int ch) 返回指定字符在此字符串中最后一次出现处的索引。 |
int | lastIndexOf(int ch, int fromIndex) 返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索。 |
int | lastIndexOf(String str) 返回指定子字符串在此字符串中最右边出现处的索引。 |
int | lastIndexOf(String str, int fromIndex) 返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。 |
int | length() 返回此字符串的长度。 |
boolean | matches(String regex) 告知此字符串是否匹配给定的正则表达式。 |
int | offsetByCodePoints(int index, int codePointOffset) 返回此 String 中从给定的 index 处偏移 codePointOffset 个代码点的索引。 |
boolean | regionMatches(boolean ignoreCase, int toffset,String other, int ooffset, int len) 测试两个字符串区域是否相等。 |
boolean | regionMatches(int toffset,String other, int ooffset, int len) 测试两个字符串区域是否相等。 |
String | replace(char oldChar, char newChar) 返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。 |
String | replace(CharSequence target,CharSequence replacement) 使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。 |
String | replaceAll(String regex,String replacement) 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。 |
String | replaceFirst(String regex,String replacement) 使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。 |
String[] | split(String regex) 根据给定正则表达式的匹配拆分此字符串。 |
String[] | split(String regex, int limit) 根据匹配给定的正则表达式来拆分此字符串。 |
boolean | startsWith(String prefix) 测试此字符串是否以指定的前缀开始。 |
boolean | startsWith(String prefix, int toffset) 测试此字符串从指定索引开始的子字符串是否以指定前缀开始。 |
CharSequence | subSequence(int beginIndex, int endIndex) 返回一个新的字符序列,它是此序列的一个子序列。 |
String | substring(int beginIndex) 返回一个新的字符串,它是此字符串的一个子字符串。 |
String | substring(int beginIndex, int endIndex) 返回一个新字符串,它是此字符串的一个子字符串。 |
char[] | toCharArray() 将此字符串转换为一个新的字符数组。 |
String | toLowerCase() 使用默认语言环境的规则将此 String 中的所有字符都转换为小写。 |
String | toLowerCase(Locale locale) 使用给定 Locale 的规则将此 String 中的所有字符都转换为小写。 |
String | toString() 返回此对象本身(它已经是一个字符串!)。 |
String | toUpperCase() 使用默认语言环境的规则将此 String 中的所有字符都转换为大写。 |
String | toUpperCase(Locale locale) 使用给定 Locale 的规则将此 String 中的所有字符都转换为大写。 |
String | trim() 返回字符串的副本,忽略前导空白和尾部空白。 |
static String | valueOf(boolean b) 返回 boolean 参数的字符串表示形式。 |
static String | valueOf(char c) 返回 char 参数的字符串表示形式。 |
static String | valueOf(char[] data) 返回 char 数组参数的字符串表示形式。 |
static String | valueOf(char[] data, int offset, int count) 返回 char 数组参数的特定子数组的字符串表示形式。 |
static String | valueOf(double d) 返回 double 参数的字符串表示形式。 |
static String | valueOf(float f) 返回 float 参数的字符串表示形式。 |
static String | valueOf(int i) 返回 int 参数的字符串表示形式。 |
static String | valueOf(long l) 返回 long 参数的字符串表示形式。 |
static String | valueOf(Object obj) 返回 Object 参数的字符串表示形式。 |
由于空间加时间有限,我就简单的说一下我自己绝得比较实用的方法
public char charAt(int index):获得第几个字符(第一个为0)
抛出的异常:
-
IndexOutOfBoundsException
- 如果index
参数为负或小于此字符串的长度。
public boolean contains(CharSequence s):比较是否含有某个字符(串)
抛出异常:空指针异常等
当然,这是我最喜欢用的
当然,少不了大家常看到的hascode();
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
由于太多了,懒得写,大家自己去看看jdk吧,至于为什么是1.6.嘿嘿,我是学Android的
最后想了想,上点代码最实际
public class MyTest {
String string=new String("123hu胡");
public MyTest() {
System.out.println(string);
System.out.println(string.concat("hu"));//加上
System.out.println(string.hashCode());
System.out.println(string.charAt(5));//不能达到6
System.out.println(string.indexOf("胡"));
System.out.println(string.getBytes());
System.out.println(string.indexOf("hu"));
//System.out.println(string.getChars(0,5, a,5 ));
System.out.println(string.substring(string.indexOf("h")));
System.out.println(string.substring(string.indexOf("h"), string.indexOf("u")));
}
public static void main(String[] args) {
new MyTest();
}
}
都比较简单,主要是substring这部分jdk没有。可能是我的jdk的问题
至于运行结果,大家自己试试把