欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

4.字符串

程序员文章站 2022-03-08 14:08:45
...

一.String

  1. 字符序列:把多个字符按照一定的顺序排列起来,
    字符串:把多个字符串连起来.
  2. 字符串的分类:
    不可变的字符串:String当前对象创建完毕之后,该对象的内容(字符序列)是不能改变的,一旦内容改变
    就是一个新的对象.
  3. 可变的字符串:StringBuilder/StringBuffer:当对象创建完毕后,该对象的内容可以发生改变,当内容
    发生改变的时候,对象保持不变
  4. 字符串的本质(底层):
String str = "ABCD";//定义一个字符串对象,等价于
char[] cs = new char[]{'A','B','C','D'};

  1. String对象的创建:
    1. 直接赋值一个字面量: String str1 = “ABCD”;
    2. 通过构造器创建: String str2 = new String(“ABCD”);
  2. String对象的空值:
    1. 表示引用为空(null):String str1 = null; 没有初始化,没有分配内存空间
    2. 内容为空字符串: String str2 = “”; 有初始化,分配了内存空间,只是没有内容。
  3. 判断字符串非空:
    1. 引用不能为空(null);
    2. 内容不能为空("");
  4. 字符串的比较操作:
    1. 使用“==”号: 只能比较引用的内存地址是否相同
    2. 使用equals方法: 在Object类中和“==”相同,建议子类覆盖equals方法去比较自己的内容。
  5. String类覆盖equals方法,比较的是字符内容。

面试题1:

  1. 下列代码分别创建了几个String对象。
String str1 = "ABCD";

最多创建一个String对象,最少不创建Srting对象。
如果常量池中,以及存在“ABCD”,那么str直接引用,此时不创建String对象。
否则,先在常量池先创建"ABCD"内存空间,再引用

String str2 = new String("ABCD");

最多创建两个String对象,至少创建一个String对象。
new关键字:绝对会在堆空间,创建内存区域,所以至少创建一个String对象

面试题2:

  1. 说说str1与其他对象的引用是否相等:

4.字符串

  1. String对象比较:

    1. 单独使用“”引号创建的字符串都是直接量,编译期就已经确定存储到常量池中
    2. 使用new String(“”)创建的对象会存储到堆内存中,是运行期才创建
    3. 使用只包含直接量的字符串连接符如“aa”+"bb"创建的也是直接量,编译期就能确定存储到常量
      池中。
    4. 使用包含String直接量(无final修饰符)的字符量表达式(“aa”+s1)创建的对象是运行期才创
      建的,存储到堆中;
      通过变量、调用方法去连接字符串,都只能在运行时期才能确定变量的值和方法的返回值,不
      存在编译优化操作。
  2. String中的常用方法:

    1. String的创建和转换:
    byte[]	getBytes():把字符串转换为byte数组
    String(byte[] bytes):把byte数组转换为字符串
    
    char[]	toCharArray():把字符串转换为char数组
    String(char[] value):把char数组转换为字符串
    
    1. 获取字符串信息
    int length() 返回此字符串的长度
    char charAt(int index) 返回指定索引处的char值 
    int indexOf(String str) 返回指定字字符串在此字符串中第一次出现出的索引
    int lastIndexOf(String str) 返回指定子字符串在此字符串中最右边出现处的索引
    
    1. 字符串比较判断
    boolean equals(Object anObject) 此字符与指定的对象比较
    boolean equalsIgnoreCase(String anotherString) 将此String与另一个String比较,不考虑大小写
    boolean contentEquals(CharSequence cs) 底层和equals相同
    
    1. 字符串大小写转换
    String toUpperCase();//小转大
    String toLowerCase();//大转小
    

新建StringDemo.java

public class StringDemo {
	public static void main(String[] args) {
		buiderString();
		getStringInfo();
		equalsString();
		toUpper_Lower();
	}
	//大小写转换
	private static void toUpper_Lower() {
		System.out.println("ABCsdsfsf".toUpperCase());
		System.out.println("ABCsdsfsf".toLowerCase());
	}
	//比较String
	private static void equalsString() {
		String s = new String( "ABCD");
		String s2 = new String( "ABCD");
		System.out.println(s == s2);//false
		System.out.println(s.equals(s2));//true
		System.out.println("ABCD".equals("abcd"));//false
		System.out.println("ABDC".equalsIgnoreCase("abcd"));//true
		System.out.println("ABCD".contentEquals("ABCD"));//true
		System.out.println("----------------------");		
	}
	//获取String信息
	private static void getStringInfo() {
		/**
		int length() 返回此字符串的长度
		char charAt(int index) 返回指定索引处的char值 
		int indexOf(String str) 返回指定字字符串在此字符串中第一次出现出的索引
		int lastIndexOf(String str) 返回指定子字符串在此字符串中最右边出现处的索引
		 */
		System.out.println("ABS DG ".length());
		//返回指定索引的值
		System.out.println("ABCD E".charAt(4));
		//返回指定字字符串在此字符串中第一次出现出的索引
		System.out.println("ADCSDIA".indexOf("DI"));
		//返回指定子字符串在此字符串中最右边出现处的索引
		System.out.println("AKDJLAS".lastIndexOf("JL"));
		System.out.println("----------------------");		
	}
	//String与char[]和byte[]转换
	private static void buiderString() {
		//字符串与byte数组的转换
		String s = "ABCD";
		System.out.println(Arrays.toString(s.getBytes()));
	   System.out.println(new String(s.getBytes()));
	   //字符串与char数组的转换
	   System.out.println(Arrays.toString(s.toCharArray()));
	   System.out.println(new String(s.toCharArray()));
	   System.out.println("----------------------");
	}
}

String练习操作

新建StringDemo2.java

public class StringDemo1 {
	public static void main(String[] args) {
		getExtension();
		firstCapital();
	}
	//首字母改为大写
	private static void firstCapital() {
		String s = "adsdSSDD";
		String str = s.substring(0, 1).toUpperCase();//截取首字母变为大写
		str += s.substring(1);//截取首字母后的字符串拼接
		System.out.println(str);
	}

	//获得Hello文件的拓展名
	private static void getExtension() {
		String s = "Hellor.java;Text.java;Hello.text;Hello.class";
		//1)获取文件名和拓展名
		String[] s1 = s.split(";");
		//2)获取Hello文件
		for (String str : s1) {
			//System.out.println(str.substring(0,str.indexOf(".")));//截取索引0到“.”之间的字符串
			if ("Hello".equals(str.substring(0,str.indexOf(".")))) {
				System.out.println(str.substring(str.lastIndexOf(".")));
			}
		}		
	}
}

String工具类的封装

新建StringUtil.java

public class StringUtil {
	//私有化构造器,防止new对象
	private StringUtil() {}
	//判非空
	public static boolean nonNull(String s) {
		return s != null && s.trim() != "";
	}
	//判空
	public static boolean stringNull(String s) {
		return !nonNull(s);
	}
}

新建测试类StringUtilDemo.java

public class StringUtilDemo {
	public static void main(String[] args) {
		boolean b = StringUtil.nonNull("");
		System.out.println(b);
		String s = null;
		b = StringUtil.stringNull(s);
		System.out.println(b);
	}
}

二.StringBuilder

  1. 分别使用String/StringBuffer/StringBuilder类拼接30000次字符串,对比各自耗时:

    1. String做字符串拼接时,性能极地(耗时),原因String时不可变的,每次内容改变都会在内存创建新的
      的对象.
    String 3997ms
    StringBuffer 5ms
    StringBuilder 2ms
        
    
    
    新建StringTime.java
    public class StringTime {
    	public static void main(String[] args) {
    		stringTime();
    		StringBufferTime();
    		StringBuilder();
    
    	}
    
    	//使用StringBuilder拼接30000次耗时
    	private static void StringBuilder() {
    		StringBuilder str = new StringBuilder(90);
    		int i = 0;
    		Long l = System.currentTimeMillis();
    		while (i < 30000) {
    			str.append("a");
    			i++;
    		}
    		l = System.currentTimeMillis() - l;
    		System.out.println(l);
    	}
    
    	//使用StringBuffer拼接30000次耗时
    	private static void StringBufferTime() {
    		StringBuffer str = new StringBuffer("");
    		int i = 0;
    		Long l = System.currentTimeMillis();
    		while (i < 30000) {
    			str.append(i);
    			i++;
    		}
    		l = System.currentTimeMillis() - l;
    		System.out.println(l);
    	}
    
    	//拼接String30000次的时间
    	private static void stringTime() {
    		String str = "";
    		int i = 0;
    		Long l = System.currentTimeMillis();
    		while (i < 30000) {
    			str += i;
    			i++;
    		}
    		l = System.currentTimeMillis() - l;
    		System.out.println(l);
    	}
    
    }
    
  2. 结论:以后拼接字符串,通通使用StringBuilder/Stringffer,不要使用String
    StringBuffer和StringBuilder都表示可变的字符串,功能都是相同的.

  3. 唯一区别:

    1. StringBuffer:StringBuffer中的方法都使用synchronized修饰符,表示同步的,在多线程并发的时候来保
      证线程安全,保证线程安全的时候性能较低.
    2. StringBuilder:StringBuilder中的方法都不使用synchronized修饰符,不安全,但是性能较高.
    3. 使用StringBuilder无参构造器,在底层创建了一个长度为16的4. char数组:
    char[] value = new char[16];
    

此时该数组只能存储16个

4.字符串

新建StringBuilderDemo.java

public class StringBuilderDemo {
	public static void main(String[] args) {
		StringBuilder sb = new StringBuilder (20);
		//链式编程,拼接字符
		sb.append("a").append("E").append("p").append("asdjk");
		System.out.println(sb);
		//删除指定索引的字符
		sb.deleteCharAt(1);
		System.out.println(sb);
		//删除指定索引之间的字符
		sb.delete(2, 5);
		System.out.println(sb);
	}
}