Integer包装类型的比较
package com.atguigu.day19;
public class Exercise01 {
public static void main(String[] args) {
Integer i = new Integer(1);
Integer j = new Integer(1);
System.out.println(i == j); //false
/* 源码
* public static Integer valueOf(int i) {
* // 如果 i 在 IntegerCache.low(-128) 和 IntegerCache.high(127) 之间
* // 就直接返回cache 中对象
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
*/
Integer m = 1; // 自动装箱 Integer.valueOf(1)
Integer n = 1;
System.out.println(m == n);//True
Integer x = 128;
Integer y = 128;
System.out.println(x == y);//false
//如果包装类和基本数据类型 ==,比较的是数值
Integer i13=128;
int i14=128;// 比较值
System.out.println(i13==i14);//T
}
}
String类型
瞜一眼源码
String 创建的两种方式
- 方式一:直接赋值 String s = “hello”;
- 方式二:调用构造器 String s = new String(“hello”);
内存解析
两种创建String对象的区别
- 方式一:直接赋值 String s = “hello”;
- 方式二:调用构造器 String s2 = new String(“hello”);
方式一:先从常量池查看是否有“hello” 数据空间,如果有,直接指向;如果没有则重新创建,然后指向。s最终指向的是常量池的空间地址
方式二:先在堆中创建空间,里面维护了value(上面源码中value)属性,指向常量池的hello空间。如果常量池没有“hello”,重新创建,如果有,直接通过value指向。最终指向的是堆中的空间地址。
案例一
package com.atguigu.day19;
public class StringTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
String a = "abc";
String b =new String("abc");
System.out.println(a.equals(b)); //真
System.out.println(a==b); //假
System.out.println(a==b.intern());//真 //intern 表示获取常量
System.out.println(b==b.intern()); // 假 false //
}
}
案例二
package com.atguigu.day19;
public class StringTest2 {
public static void main(String[] args) {
String s1 = "atguigu";
String s2 = "java";
String s4 = "java";
String s3 = new String("java");
System.out.println(s2 == s3); //F //分析 s2指向常量池 s3指向堆
System.out.println(s2 == s4); //T // s2 和 s4 指向常量池,并是同一个常量
System.out.println(s2.equals(s3));// 比较内容, 真
Person p1 = new Person();
p1.name = "atguigu";
Person p2 = new Person();
p2.name = "atguigu";
System.out.println(p1.name.equals(p2.name)); // 真,比较内容
System.out.println(p1.name == p2.name); // 真 . //p1.name 和 p2.name 指向常量池, 并是同一个常量
System.out.println(p1.name == "atguigu"); //真, p1.name 和 “atguigu” 常量池
String q1 = new String("bcde");
String q2 = new String("bcde");
System.out.println(q1==q2); // 假 s1 指向堆 s2指向堆, 不是同一个对象
}
}
class Person {
public String name;
}
字符串特性
- String是一个final类,代表不可变的字符序列
- 字符串是不可变的。一个字符串对象一旦被分配,其内容是不可变的.
题一
以下语句创建了几个对象?画出内存布局图。
String s1 = “hello”;
s1=“haha”; //2
题二
String a = “hello”+“abc”;
创建了几个对象?几个?
只有一个对象 1个对象
分析
- 编译器底层会做优化
- 等价 String a = “hello”+“abc”; => String a = “helloabc”
题三
String a = “hello”;
String b =“abc”;
String c=a+b; 创建了几个对象?三个对象
// 但是当变量相加时, a + b 时,底层使用的 StringBuilder, 内容在堆
- 底层是 StringBuilder sb = new StringBuilder(a); sb.append(b); sb是在堆中,并且append是在原来字符串的基础上追加的.
- 重要规则, String c1 = “ab” + “cd”; 常量相加,看的是池。 String c1 = a + b ; 变量相加,是在堆中
题四
下面代码输出什么,并说明原因.
String s1 = “atguigu”; //s1 常量池
String s2 = “java”; // s2 常量池
String s5 = “atguigujava”; // s5 常量池
String s6 = (s1 + s2).intern(); //s6 指向 常量池
System.out.println(s5 == s6); //T 【s5 和 s6 的内容相同,并且都指向池】
System.out.println(s5.equals(s6));//T [内容,相等的.]
题五
package com.atguigu.day19;
public class StringTest3 {
String str = new String("good");
final char[] ch = {'t','e','s','t'};
public void change(String str , char ch[]){
str = "test";
ch[0] = 'g';
}
public static void main(String[] args) {
StringTest3 str2 = new StringTest3();
str2.change(str2.str, str2.ch);
System.out.println(str2.str);
System.out.println(str2.ch);
//good
//gest
}
}
String类常见方法
package com.atguigu.day19;
public class StringCommonMethods01 {
public static void main(String[] args) {
// 2.equalsIgnoreCase 忽略大小写的判断内容是否相等
String username = "johN";
if ("john".equalsIgnoreCase(username)) {
System.out.println("Success!");
} else {
System.out.println("Failure!");
}
// 3.length 获取字符的个数,字符串的长度
System.out.println("李月娇".length());
// 4.indexOf 获取字符在字符串对象中第一次出现的索引(下标),索引从0开始,如果找不到,返回-1
String s1 = "wer@terwe@g";
int index = s1.indexOf('@');
System.out.println(index); // 3
// 5.lastIndexOf 获取字符子啊字符串中最后一次出现的索引,索引从0开始,如果找不到,返回-1
s1 = "wer@terwe@g@";
index = s1.lastIndexOf('@');
System.out.println(index);// 11
// 6.substring 截取指定范围的子串
String name = "hello,张三丰";
// 从下标6开始,截取到最后 (含)
// 截取后面的字符
System.out.println(name.substring(6));
//说明 截取 从下标 0(含) - 5(不含 )
System.out.println(name.substring(0,5)); //hello
}
}
String练习题一
package com.atguigu.day19;
public class StringExercise07 {
public static void main(String[] args) {
// TODO Auto-generated method stub
/*
* 判断邮箱是否合法,要求里面必须包含@和. 而且 @ 必须在. 的前面
*
*/
String email = ".tom@qqcn";
int ind1 = email.indexOf("@");
int ind2 = email.indexOf(".");
if(ind1 >0 && ind2 > ind1){
System.out.println("合法");
}else{
System.out.println("不合法");
}
/*
案例:不使用系统提供的trim 方法,自己写一个myTrim方法,去除字符串两端的空格,
比如 " hello world ".[思路分析+代码实现]
分析
1. 使用indexOf 来判断是否有 @ 和 .
2. 把得到结果的进行比较可以.
*/
String str = " hello "; // 得到 "hello"
System.out.println(myTrim(str));
}
public static String myTrim(String s){
//首先从左面找到非空格下标
int index = -1;
for (int i = 0; i < s.length(); i++) {
if(s.charAt(i) != ' '){
index = i;
break;
}
}
//从右边找到非空格的下标
int index2 = -1;
for (int i = s.length()-1; i >= 0 ; i--) {
if(s.charAt(i) != ' '){
index2 = i;
break;
}
}
//截取
return s.substring(index, index2+1);
}
}
String练习题二
package com.atguigu.day19;
public class StringCommonMethod02 {
public static void main(String[] args) {
// 1.toUpperCase转换成大写
String s = "heLLo";
System.out.println(s.toUpperCase());
// 2.toLowerCase 转成小写
System.out.println(s.toLowerCase());
// 3.concat拼接字符串
String s1 = "tom";
s1 = s1.concat("tyler").concat("smith");
System.out.println(s1);
// 4.replace 替换字符串中的字符
s1 = "张无忌 and 赵敏 赵敏 赵敏 赵敏";
// 下面是从 s1 中的所有 赵敏 替换成 周芷若
s1 = s1.replace("赵敏", "周芷若");
System.out.println(s1);
// 5.split 分割字符串, 对于某些分割字符,我们需要 转义比如 | \\等
// String poem = "鹅鹅鹅,曲项向天歌,白毛浮绿水,红掌拨清波";
String poem = "鹅鹅鹅\\曲项向天歌\\白毛浮绿水\\红掌拨清波";
// 含义是找到 poem 字符串中的 , 进行分割
String[] split = poem.split("\\\\");
for (int i = 0; i < split.length; i++) {
System.out.println(split[i]);
}
// 7.compareTo 比较两个字符串的大小,
// 如果前者大,则返回正数,后者大,则返回负数,如果相等,返回0
//如果字符长度相等,则比较的是字符的差值按第一个字符不相等的来
System.out.println("\n");
String a = "abcd";
String b = "aeea"; // d - f
System.out.println(a.compareTo(b)); // 返回值是 'c' - 'a' = 2的值
/*
* compareTo源码
* public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
*/
}
}
StringBuffer类
- java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删。
- 很多方法与String相同,但StringBuffer是可变长度的。
- StringBuffer是一个容器。
源码分析
StringBuffer类常用方法
package com.atguigu.day19;
public class StringBufferCommonMethod {
public static void main(String[] args) {
/*
* 增 append 删 delete(start,end) 改 replace(start,end,string)//将
* start----end 间的内容替换掉,不含end 查 indexOf //查找子串在字符串第1次出现的索引,如果找不到返回-1 插
* insert 获取长度 length
*
*/
StringBuffer s = new StringBuffer("hello");
// 增
s.append(',');
s.append("tom");
s.append("smith").append(100).append(true).append(10.5);
System.out.println(s);
// 删
/*
* 删除索引为>=start && <end 处的字符
*/
// 表示含义就是删除 [11,14)
s.delete(11, 14);
System.out.println(s);// hello,tomsm100true10.5
// 改
// 表示 把字符串 从 9 - 11的内容,
// 范围是 [9, 11)
s.replace(10, 11, "joker");
System.out.println(s); // hello,tomsjoker100true10.5
// 查找指定的子串在字符串第一次出现的索引,如果找不到返回-1
int indexOf = s.indexOf("tom");
System.out.println(indexOf);
// 插入
s.insert(9, "赵敏");
System.out.println(s);
// 长度
System.out.println("长度=" + s.length());
}
}
例题
package com.atguigu.day19;
public class StringBufferExercise01 {
public static void main(String[] args) {
String str = null;
StringBuffer sb = new StringBuffer();
/*
* 长度为4的原因 源码
* private AbstractStringBuilder appendNull() {
int c = count;
ensureCapacityInternal(c + 4);
final char[] value = this.value;
value[c++] = 'n';
value[c++] = 'u';
value[c++] = 'l';
value[c++] = 'l';
count = c;
return this;
}
*/
sb.append(str); //等价 sb.append("null")
System.out.println(sb.length());//4
System.out.println(sb);// “null”
StringBuffer sb1 = new StringBuffer(str);
System.out.println(sb1);
//分析
//1. str = null
/*源码
* public StringBuffer(String str) {
super(str.length() + 16);// null.length();
append(str);
}
*/
}
}