• 关于java String类(源码等)分析


    String 类

    在这里插入图片描述

    • String声明为final ,不可以被继承

    • String 实现了Serializable接口,表明字符串是可序列化的

    • String 实现了Compareble接口,表示String 可比较大小

    • String 内部定义了 final char[] value value用于存储字符串数据,表明了不可变的字符特性 ---- 1.当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value进行赋值。2.当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值。3.当调用String 的 replace 方法修改指定的字符或字符串时,也需要重新指定内存区域赋值。

    • 通过字面量的方式(区别new)去给字符串赋值,此时字符串值声明在字符串常量池中,常量池中是不会存储相同内容的字符串的。

      package StringTT;

      import org.junit.Test;

      public class Stringlei {

        @Test
        public void test1(){
        	String s1 = "abc"; // 字面量的定义方式
        	String s2 = "abc";
        
        	System.out.println(s1 == s2); // 对象比较的是地址值
        	s1 = "hello";
        
        
        
        	System.out.println(s1);
        	System.out.println(s2);
        
        	System.out.println("*****************");
        	String s3 = "abc";
        	s3 += "def" ;
        	System.out.println(s3);
        }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18

      }

    在这里插入图片描述

    创建String对象

    在这里插入图片描述
    new 是在堆空间中创建

    String s = new String(“abc”); 方式创建对象,在内存中创建了几个对象?两个:一个是堆空间new的结构,另一个是char[]对象常量池中的数据:“abc”

    package StringTT;
    
    import org.junit.Test;
    
    public class StringTest2 {
    
    
    
    
    	@Test
    	public void test(){
    	//方式一:通过字面量定义
    		String s1 = "javaEE";
    		String s2 = "javaEE";
    
    	// 方式二:用new 在堆空间中创建
    	
    		String s3 = new String("javaEE");
    		String s4 = new String("javaEE");
    	
    		System.out.println(s1 == s2);  // true
    		System.out.println(s3 == s4);  // false
    	
    	}
    }	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    常量与常量的拼接结果在常量词中,常量与变量拼接,结果就会在堆当中

    @Test
    public void test1(){
    	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;
    	
    	System.out.println(s3 == s4); // true
    	System.out.println(s3 == s5); // false
    	System.out.println(s3 == s6); // false
    	System.out.println(s3 == s7); // false
    	System.out.println(s5 == s4); // fasle
    	System.out.println(s5 == s6); // fasle
    	System.out.println(s5 == s7); // fasle
    	
    	String s8 = s5.intern(); // 得到的是在常量池
    	System.out.println(s8 == s3); // true 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    String 方法

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    String 和 char[] 的转换

    • String 转 char[] 用 String.toCharArray()方法

    • char[] 转 String 调用String 的构造器

      package StringTT;

      import org.junit.Test;

      public class StringTest1 {
      // String 和 byte的转换
      @Test
      public void test123(){
      String str1 = “abc123”;
      char[] charArray = str1.toCharArray();
      for (int i = 0;i < 100; i++){
      System.out.println(charArray[i]);
      }
      }

        @Test
        public void test2(){
        	char[] ch1 = new char[]{'h','e','l','l','o'};
        	String str2 = new String(ch1);
        	System.out.println(str2);
        }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

      }

    String 和 byte[] 的转换

    有中文的话就转不了一个数字了
    编码 :字符串 --> 字节 (看得懂 -->看不懂)String 转 byte[] 用String的getBytes()方法
    解码:字节 – > 字符串(看不懂的二进制 – > 看得懂)byte[] --> String
    解码过程中,必须与编码所使用的字符集一致

    package StringTT;
    
    import java.io.UnsupportedEncodingException;
    import java.util.Arrays;
    
    import org.junit.Test;
    
    public class StringTest1 {
    	// String  和 byte的转换
    	@Test
    	public void test123(){
    		String str1 = "abc123";
    		char[] charArray = str1.toCharArray();
    		for (int i = 0;i < str1.length(); i++){
    			System.out.println(charArray[i]);
    		}
    	}
    
    
    	@Test
    	public void test2(){
    		char[] ch1 = new char[]{'h','e','l','l','o'};
    		String str2 = new String(ch1);
    		System.out.println(str2);
    	}
    
    
    	@Test
    	public void test3() throws UnsupportedEncodingException{
    		String str1 = "abc123中国";
    		byte[] b1 = str1.getBytes(); // 使用默认的字符集进行转换
    		System.out.println(Arrays.toString(b1)); //输出
    	
    		byte[] b2 = str1.getBytes("gbk"); //使用gbk字符集进行编码
    		System.out.println(Arrays.toString(b2));
    	
    		//解码 byte[] --> String
    		String s1 = new String(b1); // 默认的字符集进行解码
    		System.out.println(s1);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    StringBuffer 、StringBuilder、String 异同

    • String 不可变的字符序列,底层用char[]进行存储
    • StringBuffer 可变的字符序列,线程安全的,效率偏低,底层用char[]进行存储
    • StringBuilder 可变的字符序列,JDK5.0新增,线程不安全,效率高,底层用char[]进行存储

    源码分析

    String str = new String();//char[] value = new char[0];
    String str = new String(“abc”); // char[] value = new char[]{‘a’,‘b’,‘c’};

    StringBuffer str = new StringBuffer();//char[] value = new char[16]; 底层创建了一个长度是16的字符数组

    StringBuffer str1 = new StringBuffer(“abc”); // char[] value = new char(“abc”.length + 16) 创建了长度为19的字符数组

    问题1:打印str1的长度是多少呢?还是3
    问题2:如果要添加的数据,底层数据盛不下了,那就需要扩容底层的数组。默认情况下,扩容为原来容量的两倍+2,同时将原有数组的元素复制到新数组中

    指导意义:开发中建议使用StringBuffer(int capacity) 或 StringBuilder(int capacity) ,就看需不需要考虑安全

    package StringTT;
    
    import org.junit.Test;
    
    public class StringBufferBuiderTest {
    	@Test
    	public void test(){
    	StringBuffer sb1 = new StringBuffer("abc");
    	sb1.setCharAt(0, 'm');
    	System.out.println(sb1);
    
    	String s1 = "abc";
    	s1.replace('a','m');
    	System.out.println(s1); //s1不变
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述
    public String substring – 返回一个start 开始 end索引结束的左闭右开区间的子字符串

    在这里插入图片描述

    效率从高到低排列:StringBuilder > StringBuffer > String

    JDK8.0之前 日期和时间API

    @Test
    public void test(){
    	long time = System.currentTimeMillis();
    	System.out.println(time);  //1970/1/1 到我们现在的时间差 毫秒数,通常叫一个时间戳
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    含文档+PPT+源码等]精品微信小程序ssm的房屋交易平台+后台管理系统|前后分离VUE[包运行成功]微信小程序项目源码Java毕业设计
    防火墙NAT智能选举综合实验
    [附源码]计算机毕业设计springboot电商小程序
    MS35774,高精度、低噪声的两相步进电机驱动芯片
    【Pytorch】torch.nn.Dropout()
    Sentinel底层原理(下)
    学会make/makefile基本用法
    华秋携手凡亿成功举办电子设计与制造技术研讨会
    inno setup自定义卸载程序和美化
    数据库小记-mysql-DDL、DML、DQL
  • 原文地址:https://blog.csdn.net/abc1234564546/article/details/127842411