String类的使用

package com.qf.string_class;

import java.util.Arrays;

public class Test01 {
	/**
	 * 知识点:字符串相关的类
	 * 分类:
	 * 		String、StringBuffer、StringBuilder
	 * 
	 * 知识点:String类的使用
	 */
	public static void main(String[] args) {
		
		
		String str = "123abc";
		
		str = str.concat("DEF123");//凭接字符串,并返回新的字符串
		
		str = str.substring(2);//从开始下标出截取到字符串末尾,并返回新的字符串
		
		str = str.substring(1, 5);//从开始下标处(包含)截取到结束下标处(排他),并返回新的字符串
		
		str = str.toUpperCase();//转大写,并返回新的字符串
		
		str = str.toLowerCase();//转小写
		
		str = "   123 abc    DEF  123    ";
		str = str.trim();//去除首尾空格,并返回新的字符串
		str = str.replace('a', 'A');//替换字符,并返回新的字符串
		str = str.replaceAll("bc", "BBCC");//替换字符串,并返回新的字符串
		str = str.replaceAll(" ", "");//将空格替换成空内容的字符串,达到去空格的效果
		
		System.out.println("判断两个字符串内容是否相同(区分大小写):" + str.equals("123ABBCCDEF123"));//true
		System.out.println("判断两个字符串内容是否相同(不区分大小写):" + str.equalsIgnoreCase("123abbccDEF123"));//true
		System.out.println("判断字符串是否以某个字符串开头:" + str.startsWith("123"));//true
		System.out.println("判断字符串是否以某个字符串结尾:" + str.endsWith("123"));//true
		
		System.out.println("判断字符串第一次出现的下标:" + str.indexOf("B"));//4
		System.out.println("判断字符串最后一次出现的下标:" + str.lastIndexOf("B"));//5
		System.out.println("获取指定下标上的字符:" + str.charAt(3));//A
		System.out.println("获取长度:" + str.length());//14

		char[] cs = str.toCharArray();//将字符串转换为字符数组(获取字符串底层的字符数组)
		System.out.println(Arrays.toString(cs));

		System.out.println(str);//123ABBCCDEF123

		//将其他类型转换为字符串 -- 方式一
		System.out.println(String.valueOf(100));//int -> String
		System.out.println(String.valueOf(123.123));//double -> String
		System.out.println(String.valueOf(true));//boolean -> String
		System.out.println(String.valueOf('A'));//char -> String

		//将其他类型转换为字符串 -- 方式二
		System.out.println(100 + "");//int -> String  自动向上转
		System.out.println(123.123 + "");//double -> String
		System.out.println(true + "");//boolean -> String
		System.out.println('A' + "");//char -> String
		
		System.out.println(str);
		
		}

}

StringBuffer的使用

public static void main(String[] args) {
		
		StringBuffer sb = new StringBuffer();
		
		sb.append("123abc");//在末尾追加字符串
		sb.append("DEF123");//在末尾追加字符串
		
		sb.insert(6, "XXXYYY");//在指定下标处插入字符串
		sb.replace(6, 12, "xxyy");//从开始下标处(包含)替换到结束下标处(排他)的字符串
		
		sb.deleteCharAt(4);//删除指定下标上的字符
		sb.delete(3, 12);//从开始下标处(包含)删除到结束下标处(排他)的字符串
		
		sb.reverse();//反转字符串
		
		//321321
		System.out.println(sb);//123abcDEF123
	}

StringBuilder的使用

public static void main(String[] args) {
		
		StringBuilder sb = new StringBuilder();
		
		sb.append("123abc");//在末尾追加字符串
		sb.append("DEF123");//在末尾追加字符串
		
		sb.insert(6, "XXXYYY");//在指定下标处插入字符串
		sb.replace(6, 12, "xxyy");//从开始下标处(包含)替换到结束下标处(排他)的字符串
		
		sb.deleteCharAt(4);//删除指定下标上的字符
		sb.delete(3, 12);//从开始下标处(包含)删除到结束下标处(排他)的字符串
		
		sb.reverse();//反转字符串
		
		//321321
		System.out.println(sb);//123abcDEF123
	}

深入String 之 创建对象问题

String str1 = "abc";//0X11
String str2 = "abc";//0X11
System.out.println(str1 == str2);//true


String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(str1 == str2);//false
//创建了三个对象,“abc”放在常量池中+还new了两个对象

深入String 之 拼接字符串问题

public static void main(String[] args) {
		String str1 = "abc";
		String str2 = "abc";
		System.out.println(str1 == str2);//true
		
		//注意:字面值常量在编译时就直接拼接
		String str3 = "ab" + "c";
		System.out.println(str1 == str3);//true
		
		//注意:常量在编译时就直接拼接
		final String s1 = "ab";
		final String s2 = "c";
		String str4 = s1 + s2;
		System.out.println(str1 == str4);//true
		
		String s3 = "ab";
		String s4 = "c";
		String str5 = s3 + s4;//底层实现:new StringBuilder(String.valueOf(s3)).append(s4).toString()
		System.out.println(str1 == str5);//false
	}

StringBuilder和StringBuffer的底层原理

  • 知识点:StringBuilder和StringBuffer的底层原理
    继承关系:
    StringBuilder extends AbstractStringBuilder
    StringBuffer extends AbstractStringBuilder
    小结:
    1.StringBuilder和StringBuffer将数据存储在父类AbstractStringBuilder中的char类型的数组中
    2.缓冲数组的默认大小16
    3.StringBuilder的功能完全依赖父类AbstractStringBuilder
    4.StringBuffer的功能完全依赖父类AbstractStringBuilder
    5.StringBuilder和StringBuffer的使用是一模一样的
    6.StringBuilder是线程不安全的,单线程下使用
    7.StringBuffer是线程安全的,多线程下使用 - synchronized
public static void main(String[] args) {

		//默认缓冲区大小:16
		//StringBuilder sb = new StringBuilder();
		//自定义缓冲区大小:100
		//StringBuilder sb = new StringBuilder(100);
		//自定义缓冲区大小:"123aaa".length() + 16
		//		StringBuilder sb = new StringBuilder("123aaa");
		//		sb.append("123abc");
		//		sb.append("DEF123");
		//		System.out.println(sb);

		//默认缓冲区大小:16
		//MyStringBuilder msb = new MyStringBuilder();
		//自定义缓冲区大小:100
		//MyStringBuilder msb = new MyStringBuilder(100);
		//自定义缓冲区大小:"123aaa".length() + 16
		//		MyStringBuilder msb = new MyStringBuilder("123aaa");
		//		msb.append("123abc");
		//		msb.append("DEF123");
		//		System.out.println(msb);

		//--------------------------------------------------------------------------------

		//默认缓冲区大小:16
		//StringBuffer sb = new StringBuffer();
		//自定义缓冲区大小:100
		//StringBuffer sb = new StringBuffer(100);
		//自定义缓冲区大小:"123aaa".length() + 16
		//		StringBuffer sb = new StringBuffer("123aaa");
		//		sb.append("123abc");
		//		sb.append("DEF123");
		//		System.out.println(sb);

		//默认缓冲区大小:16
		//MyStringBuffer msb = new MyStringBuffer();
		//自定义缓冲区大小:100
		//MyStringBuffer msb = new MyStringBuffer(100);
		//自定义缓冲区大小:"123aaa".length() + 16
		MyStringBuffer msb = new MyStringBuffer("123aaa");
		msb.append("123abc");
		msb.append("DEF123");
		System.out.println(msb);
}

String vs StringBuilder vs StringBuffer

  • String的理解:
String是不可变类, 即一旦一个String对象被创建,
包含在这个对象中的字符序列是不可改变的, 直至该对象被销毁。
String类是final类,不能有子类。
public class String{
private final char[] value;
}
  • StringBuilder和StringBuffer的理解:
StringBuilder和StringBuffer称为字符串缓冲区,
它的工作原理是:new对象预先申请一块内存,存放字符序列(字符数组),
默认大小为16个长度,如果字符序列满了,会重新改变缓存区的大小(扩容机制:原来长度*2+2),
以容纳更多的字符序列。
StringBuilder和StringBuffer是可变对象(可扩容),这个是String最大的不同
StringBuilder和StringBuffer代表可变的字符序列。

频繁的字符串拼接请使用StringBuilder或StringBuffer

public static void main(String[] args) {
		//获取1970年1月1日到现在的毫秒数(1秒 = 1000毫秒)
		//long currentTime = System.currentTimeMillis()ss

//		long startTime = System.currentTimeMillis();
//		String str = "用良心做教育";
//		for (int i = 0; i < 10000; i++) {
//			str += "用良心做教育";
//			//底层原理:
//			//	str = str + "用良心做教育";
//			//	str = new StringBuidler(String.valueOf(str)).append("用良心做教育").toString();
//		}
//		System.out.println("字符串长度:" + str.length());
//		long endTime = System.currentTimeMillis();
//		System.out.println("消耗时长:" + (endTime-startTime));//380毫秒

		long startTime = System.currentTimeMillis();//单例模式,懒汉式
		StringBuilder sb = new StringBuilder(60006);
		sb.append("用良心做教育");
		for (int i = 0; i < 10000; i++) {
			sb.append("用良心做教育");
		}
		System.out.println("字符串长度:" + sb.length());
		long endTime = System.currentTimeMillis();
		System.out.println("消耗时长:" + (endTime-startTime));//1毫秒

	}