java 总结(String类、StringBuffer类)

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 创建的两种方式

  1. 方式一:直接赋值 String s = “hello”;
  2. 方式二:调用构造器 String s = new String(“hello”);

内存解析
在这里插入图片描述
两种创建String对象的区别

  1. 方式一:直接赋值 String s = “hello”;
  2. 方式二:调用构造器 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;
}

字符串特性

  1. String是一个final类,代表不可变的字符序列
  2. 字符串是不可变的。一个字符串对象一旦被分配,其内容是不可变的.

题一
以下语句创建了几个对象?画出内存布局图。
String s1 = “hello”;
s1=“haha”; //2
在这里插入图片描述

题二
String a = “hello”+“abc”;
创建了几个对象?几个?
只有一个对象 1个对象

分析

  1. 编译器底层会做优化
  2. 等价 String a = “hello”+“abc”; => String a = “helloabc”

题三
String a = “hello”;
String b =“abc”;
String c=a+b; 创建了几个对象?三个对象
// 但是当变量相加时, a + b 时,底层使用的 StringBuilder, 内容在堆

  1. 底层是 StringBuilder sb = new StringBuilder(a); sb.append(b); sb是在堆中,并且append是在原来字符串的基础上追加的.
  2. 重要规则, 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类

  1. java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删。
  2. 很多方法与String相同,但StringBuffer是可变长度的。
  3. 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);
				    }
		*/


	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值