String
java.lang.String 是字符串
它的底层是一个字符数组,所以它的很多特性就是数组的特性
1 字符串一旦被创建,这个字符串对象就不可以更改了
2 为了提升字符串的访问效率,java虚拟机采用了一种缓存的技术,String是一个引用数据类型,那么String的值应该保存在堆内存吧?
但是字符串不一样,字符串对象都会在静态区有一个字符串常量池
3 在程序执行中,如果程序要用到某一个字符串,比如(“abc”),虚拟机首先会去字符串常量池中搜索,有没有这个字符串,
如果已经有了,就直接指向这个字符串,不需要再创建一个
如果没有,就创建一个,然后再指向
public class String_01 {
public static void main(String[] args) {
//创建一个abc字符串对象,直接保存再常量池中,然后将内存地址赋值给变量s1
//尽管没有new但是s1还是指向字符串对象
String s1 = "abc";
//s1是main方法中局部变量,并且没有使用final修饰,所以可以更改s1的值
//因为s1只保存了一个内存地址,所以s1可以重新赋值一个新的内存地址
//但是abc对象,更改不了
s1 = "def";
String s2 = "Hello";
String s3 = "Hello";
String s4 = "hello";
System.out.println(s2 == s3);
System.out.println(s2.toString());
System.out.println(s2.equals(s3));
//创建两个对象,一个Hello 一个hello
//true比较值,因为String覆写了
System.out.println(s2.equals(s3));
String s5 = new String("abc");
String s6 = new String("abc");
//false,因为这种方法,s5和s6分别指向堆内存,堆内存再指向数据
System.out.println(s5 == s6);
System.out.println(s5.equals(s6));
}
}
注意
使用String的时候,要注意,尽量不要做频繁的拼接操作
因为字符串一旦创建,不能更改,如果拼接,会频繁的创建字符串对象,浪费空间
public class String_02 {
public static void main(String[] args) {
String[] arr = {"a","b","c"};
String tmp = "";
for(int i = 0;i < arr.length;i++) {
tmp += arr[i];
}
//a,b,c,ab,abc
System.out.println(tmp);
}
}
String的构造方法
public class String_03 {
public static void main(String[] args) {
//1
String s1 = "abc";
//2
String s2 = new String("abc");
//3 传递字节数组,转换为字符串
byte[] bytes = {97,98,99};
String s3 = new String(bytes);
System.out.println(s3);
//4 截取字节数组中的一部分
//下标从1开始(包含), 取两个
String s4 = new String(bytes,1,2);
System.out.println(s4);
//5 传递字符串数组,转换为字符串
char[] chars = {'q','w','e','r'};
String s5 = new String(chars);
System.out.println(s5);
//6 截取字符数组的一部分
String s6 = new String(chars,0,2);
System.out.println(s6);
}
}
String常用方法
public class String_04 {
public static void main(String[] args) {
// 1 char charAt(int index):获取字符串中,某个位置上的字符,相当于arr[index]
String s1 = "qwer";
char c1 = s1.charAt(2);
System.out.print(c1);
//2 boolean endsWith(String suffix):判断字符串是否以指定字符串结尾
//startsWith(String prefix)判断开始
//true
System.out.println("Hello.java".endsWith(".java"));
//false 注意 空格
System.out.println("Hello.java".endsWith(".java "));
//3 boolean equalsIgnoreCase(String anotherString):不区分大小写比较两个字符串是否相等
System.out.println("abc".equals("ABC"));
System.out.println("abc".equalsIgnoreCase("ABC"));
//4 byte[] getBytes();:把字符串转换为字节数组
byte[] bytes = "abc".getBytes();
for(byte b : bytes) {
System.out.println(b);
}
System.out.println("-----");
//5 int indexOf(String str): 获取指定字符串的起始索引,找不到就返回-1
System.out.println("cniuhaushd213hxhdd2".indexOf("d2"));//9
//6 int indexOf(String str,int fromIndex): 从指定位置开始查找,找不到返回-1
System.out.println("cnuasdjkdncu22123nnnadios".indexOf("c",1));
//7 int lastIndexOf(String str):最后一次出现位置的索引,找不到返回-1
System.out.println("dasdasdadaojf12eoijo".lastIndexOf("c"));
//8 int length(): 获取字符串长度
System.out.println("abc".length());
//9 String replaceAll(String regex,String replacement):把指定字符换为指定字符
//还有一个方法replace这两个功能一样,只不过replaceAll支持正则表达式
System.out.println("12h,dha!sioh@#21从!23<>".replaceAll("[^0-9a-zA-Z]", "" ));
//10 Strubg[] split(String regix):分割字符串,需要指定分隔符,返回值是字符串数组,支持正则表达式
String myTime = "2008,08,08";
//如果是以.点分割,需要\\.因为split支持正则表达式,在正则表达式中有特殊含有,所以需要转义
//在正则表达式中,通过\.对.进行转义,但是\在java中也是转移服,所以需要\\.来转义\
String[] ymd = myTime.split(",");
for(String string : ymd) {
System.out.println(string);
}
System.out.println("----");
//11 String substring(int begin):获取该字符串以某个下标开始的字符串(包含)
System.out.println("abcdefg".substring(2));//cedfg
//12 String substring(int beginIndex,int endIdex);"
//以某个下标开始(包含),到某个下标结束的子字符串(不包含)
System.out.println("abcdefg".substring(2,6));//cdef
//13 char[] toCharArray():转换为char数组
char[] c2 = "qwer".toCharArray();
for(char c : c2) {
System.out.println(c);
}
System.out.println("----");
//14 转大写和小写
System.out.println("asdUId".toUpperCase());
System.out.println("asdUId".toLowerCase());
//15 String trim():去除字符串首尾的空格
System.out.println(" 1 dcz s ".trim());
//16 static String valueOf(Object obj): 调用对象的toString方法,并处理null值
}
}
String是不能任意拼接的字符串
public class String_06 {
public static void main(String[] args) {
// String是不能任意拼接的字符串
String s1 = "ab";
String a = "a";
String b = "b";
//两个字面量相加,在编译阶段,会把+去掉,这个 + 相当于字符串连接符
String s3 = "a" + "b";
//这种不一样,因为在编译,没有办法确定a和b的值的,所以只能等运行起来之后在操作
//会创建一个StringBuffer对象进行拼接,然后再通过toString方法把拼接之后的值返回
//因为toString方法中,是new String(xxx);的形式返回,所以会指向堆内存
//所以使用 == 比较就不对,equals()比较 就没有问题
//所以 不管哪种赋值方式,我们比较字符串就使用equals()是最正确的,也是最保准的
String s2 = a + b;
String s4 = "a" + new String("b");
System.out.println(s1 == s2);//false
System.out.println(s1 == s3);//true
System.out.println(s1 ==s4);//false
System.out.println(s1.equals(s4));
}
}