String类:
代表字符串, java程序中的所有字符串字面值(如, "abc")都是此类的实例实现
String是一个final类,代表不可变的字符序列
字符串是常量是用双引号引起来的,他们的值再创建后不可以修改
String对象的字符内容是存储再一个字符数组Value[]中的
源码:
表现:
扫描二维码关注公众号,回复:
8270561 查看本文章
String对象的创建
String name = "hello"; String的值底层都是存储再char [] 数组内 // 本质上this.value = new char[0]; string s1= new String() ; // this.value = ori.value String s2 = new String(String ori)
字符串对象的存储
字符串对象分为: 常量 和 非常量对象
String常量: 创建是不带new String name = "老王";
非常量: 创建是带new : String name = new String("老王");
字符串常量: String name = "老王"; 字符串非常量对象: String name = new String("老王");
放置的位置:
字符串非常量放置在常量池内, 常量池内相同的值共享
非常量对象放置在堆中,值不可以共享
存储位置不同:
字符串非常量放置在常量池内, 常量池内相同的值共享
非常量对象放置在堆中,值不可以共享
常量池内的值是可以共享的 我们定义的时候可以不用再开辟其余的空间了,这种方法省消耗
String再创建的时候value存储的位置也是不同的,虽然底层都是默认存储再char[] 中,但是 其存储的位置有时也是不同的
// 通过字面量定义的方式, 此时的s1的数据 声明再方法区中字符串常量池中 String s1 = "abc"; String s2 = "abc"; System.out.println(s1 == s2); // true // new+构造器的方式此时的s3保存的地址值 是数据在堆中开辟的新空间保存的地址值 String s3 = new String("javaEE");
常量对象和非常量对象既然存储不同那么值肯定不能用==
常量对象非常量对象练习题:
求出下面输出的内容
// 通过字面量的定义方式: 此时的s1 和s2 定义在字符串常量池中 String s1 = "javaEE"; String s2 = "hadoop"; String s3 = "javaEEhadoop"; String s4 = "javaEE"+"hadoop"; String s5 = s1 +"hadoop"; String s6 = "javaEE"+s2; String s7 = s1+s2; String s8 = s6.intern(); System.out.println(s3 == s4); // System.out.println(s3 == s5); // System.out.println(s3 == s6); // System.out.println(s3 == s7); // System.out.println(s5 == s6); // System.out.println(s5 == s7); // System.out.println(s6 == s7); // System.out.println(s3 == s8); //
结果:
true false false false false false false true
因为携带变量名的都是存储在堆空间中的不是存储在常量池中,因为变量名拿到的都是讲指向堆中的地址值
结论:
1: 常量与常量的拼接在常量池内,且常量池内不会存储相同的内容的常量,同一个常量池中的常量地址都相同 2: 只要一个是变量,那么结果就是堆中,堆中的值都是地址不同的 3: 如果拼接的结果调用intern()方法,返回值就在常量池中
总结:
String 的使用 1:String的声明是使用一对 " " 引起来表示的 2: String 的声明为final的不可被继承 3: String 实现了Serializable接口 可序列化, 表示字符串是支持序列化 实现了Comparable接口 表示String可以比较大小 4: String在内部定义了final, char[] value用于存储字符串数据 5: String代表一个不可变的字符序列, 简称不可变 体现: a: 当对字符串重新赋值时 需要重写指定内存区域赋值, 不能使用原有的value进行赋值 b: 当对现有的字符串进行连接操作时重新赋值后, 也需要重新指定内存区域 c: 当调用String的replace()方法修改字符串时,也必须重新指定内存区域 *** 6: 通过字面量的方式(区别于new) 给一个字符串赋值 String name = "老王";此时的字符串声明在字符串常量中 7: 字符串常量池中是不会存储相同内容的字符串的
面试题:
1:
String s = new String("abc"); 方式创建对象, 在内存中创建了几个对象
创建了两个对象,
第一个是堆空间中new的结构 第二个是char[] 数组 ,对应的常量池中的数据"abc"
2:
public class StringTestTwo { public static void main(String[] args) { StringTT stringTT = new StringTT(); stringTT.change(stringTT.str, stringTT.ch); System.out.println(stringTT.str+"and"); stringTT.change("laowang", new char[]{'0'}); System.out.println(stringTT.ch); // best } } class StringTT{ String str = new String("good"); char [] ch = {'t', 'e', 's', 't'}; public void change(String str , char [] ch){ str = "test ok"; ch[0] = 'b'; System.out.println(str); } }
解答:
test ok
goodand 因为String是不可变的你的变了 但是我的仍然不变
test ok
best
String 的操作方法
int length():返回字符串的长度: return value.length char charAt(int index): 返回某索引处的字符return value[index] boolean isEmpty():判断是否是空字符串:return value.length == 0 String toLowerCase():使用默认语言环境,将 String 中的所有字符转换为小写 String toUpperCase():使用默认语言环境,将 String 中的所有字符转换为大写 String trim():返回字符串的副本,忽略前导空白和尾部空白 boolean equals(Object obj):比较字符串的内容是否相同 boolean equalsIgnoreCase(String anotherString):与equals方法类似,忽略大 小写 String concat(String str):将指定字符串连接到此字符串的结尾。 等价于用“+” int compareTo(String anotherString):比较两个字符串的大小 String substring(int beginIndex):返回一个新的字符串,它是此字符串的从 beginIndex开始截取到最后的一个子字符串。 String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字 符串从beginIndex开始截取到endIndex(不包含)的一个子字符串。 boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束 boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始 boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的 子字符串是否以指定前缀开始 boolean contains(CharSequence s):当且仅当此字符串包含指定的 char 值序列 时,返回 true int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引 int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出 现处的索引,从指定的索引开始 int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引 int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后 一次出现处的索引,从指定的索引开始反向搜索 注:indexOf和lastIndexOf方法如果未找到都是返回-1 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 替换此字符串匹配给定的正则表达式的第一个子字符串。 boolean matches(String regex):告知此字符串是否匹配给定的正则表达式。 String[] split(String regex):根据给定正则表达式的匹配拆分此字符串。 String[] split(String regex, int limit):根据匹配给定的正则表达式来拆分此 字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中。
eg:
String.length() // 求出字符串的长度
// 求出String 字符串的长度 String.length() System.out.println(name.length()); // 2 System.out.println(EnglishName.length()); // 7
String.charAt() 返回指定索引中字符串中的内容
// 返回指定索引中的字符串中的字符 String.charAt(index); 不要以为只能怼字符串中的字符使用 还可以对汉字使用 System.out.println(name.charAt(1)); // 王 System.out.println(EnglishName.charAt(3)); // w
isEmpty() 判断字符串是否是空
// isEmpty() 判断字符串是否是空 String s1 = ""; System.out.println(name.isEmpty()); // false System.out.println(s1.isEmpty()); // true
toLowerCase() 字符串所有的字母都转为小写
// toLowerCase() 将String中的字符全部小写 String s2 = "Laowang"; String lowerCase = "你好WOde"; System.out.println(lowerCase.toLowerCase()); // 你好wode System.out.println(name.toLowerCase()); // 老王 汉字不会报错 System.out.println(s2.toLowerCase()); // L小写 laowang
toUpperCase() 字符串中所有的字母都大写
// toUpperCase() 将String中的字符全部大写 System.out.println(EnglishName.toUpperCase()); // LAOWANG
trim() 祛除首尾空格
// trim() 去除字符串首尾的空格 String s3 = " ni "; System.out.println(s3.trim());
equals() 比较两个字符串内容是否相同
== 比较的是内存地址值, equals() 比较的是大小
// equals() 比较字符串中的内容是否相同 System.out.println(name.equals(EnglishName)); // false
equalsIgnoreCase() 也是比较两个字符串大小,忽略大小写
// equalsIgnoreCase() 和equals()相同只是忽略大小写 String s4 = "LAOLI"; String s5 = "laoli"; System.out.println(s4.equalsIgnoreCase(s5)); // true
concat() 拼接,相等于"+",把两个字符串相加一起
// concat() // 拼接 把两个字符串拼接再一起 ,相当于+ System.out.println(name.concat(EnglishName)); // 老王laowang
.