String 类

String 类

概述

  • String 是一种非常特殊的类,代表字符串,Java 程序中的所有字符串字面值,例如"abc"都作为 String 类的实例实现;
  • String 是一个 final 类, 他的底层是一个 char 类型的 final 数组,代表不可变的字符序列。字符串是常量,用双引号引起来表示,他们的值在创建之后不能更改;
  • String 实现了 Serializable 接口、表示字符串是支持序列化的,实现了 Comparable 接口,表示 String 类型的字符可以比较大小;

实例化方式:

两种实例化方式

方式一:通过字面量定义的方式

  • String s = "abc132"; 是一种非常特殊的形式,这里暂且叫他形式赋值(字面量) 其在 Java 中被叫做直接量,跟 new 有着本质的区别 ,他是 Java 中唯一一个不需要 new 就产生的对象,本方法产生的数据存放在方法区的常量池中;

方式二:通过 new + 构造器的方式

  • new 出来的对象通常会被放在堆里 而 形式赋值产生的直接量在创建的时候 会在 JVM 内部发生字符串扣留 -->1.先查看常量池中是否有内容相同的字符串,若有 ,则将其直接指向常量池中已有的字符串 ,偌常量池中没有声明的该字符串,则创建一个字符串将其放入常量池中;
String s = "abc";
s += "def"; // 这里也是会直接重新创建一个内存区域用来存储连接过的字符串 
//当调用 String.replace 来修改字符串内容时,也会直接创建一个新的内存区域用来存储

若两种方式创建的方法不同,但是内容相同,那么 new 出来的 String 对象里的属性指向的还是同一个方法区里的常量池中的数据的地址;

String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
String s4 = new String("abc");
System.out.println(s1 == s2); //true
System.out.println(s1 == s3); //false
System.out.println(s3 == s4); //false

上述例子中,如果有变量参与进来,那么其将会被定义在堆空间当中,在堆空间当中 new 一个变量;

但是常量与常量的拼接结果在常量池,且常量池中不会存在相同内容的常量

intern( ):在调用 "ab".intern() 方法的时候会返回 ”ab”,但是这个方法会首先检查字符串池中是否有”ab”这个字符串,如果存在则返回这个字符串的引用,否则就将这个字符串添加到字符串池中,然会返回这个字符串的引用;

String 类常会用到的方法

String s1 = "Hello World"; 
System.out.println("原版" + s1); //原版 Hello World              
  • 从指定的字符串中,截取某一字符串
String str = "dsadasdaux1112";
int aux11 = str.indexOf("aux11");
String substring = str.substring(aux11, aux11 + 5);
System.out.println(substring);
  • 获取字符串长度 --> length
System.out.println(s1.length());  //11              
  • 取指定索引位置的字符-->charAt(int index )
System.out.println(s1.charAt(0)); //H 
System.out.println(s1.charAt(6)); //W
System.out.println(s1.charAt(7)); //o
  • 判断字符串是否为空 返回布尔类型-->isEmpty( )
System.out.println(s1.isEmpty()); //false
  • 转换大小写**--> **toLowerCase( )、toUpperCase( )
String s2 = s1.toLowerCase();//小写  //新创建
System.out.println(s1);  //Hello World
System.out.println(s2); //小写  hello world
String s3 = s1.toUpperCase(); 
System.out.println(s3);//大写 HELLO WORLD
  • 忽略前导和尾部空白-->trim( )
String s4 = "   hello wo r l d  ";
String s5 = s4.trim();
System.out.println("--" + s4 + "--");//--   hello wo r l d  -- S
ystem.out.println("--" + s5 + "--"); //--hello wo r l d--       
  • equals()比较字符串内容
  • equalsIgnoreCase 忽略大小写比较
String s6 = "hello world";
System.out.println(s6.equals(s1));//false 
System.out.println(s6.equalsIgnoreCase(s1)); //true              
  • 连接字符 concat
String s7 = s1.concat("哈哈哈");
System.out.println(s7); //Hello World哈哈哈
  • compareTo 调用者-被调用者 这里 a-b
String a = "a";
String b = "b";
System.out.println(a.compareTo(b)); // a -b = -1  会涉及到字符串排序
  • 提取字符串
String s8 = s1.substring(0, 5); // 左闭右开区间
System.out.println(s8); // Hello
System.out.println(s1); // Hello World
  • endWith 是否以指定字符串结尾
boolean ld = s1.endsWith("ld");
System.out.println(ld); //true
  • startWith 是否以指定字符串开始
boolean hell = s1.startsWith("Hell");
System.out.println(hell); //true
  • 字符串是否包含字符
boolean hello = s1.contains("Hello");
System.out.println(hello); //true
  • indexOf 查找指定字符第一次出现的位置的索引
int wo = s1.indexOf("Wo"); // 有则返回索引 无则返回 -1 
System.out.println(wo); // 6 
int lo = s1.indexOf("lo", 2); 
System.out.println(lo); //3              
  • lastIndexOf 从后往前找
  • replaceAll 把字符串中的数字替换成,如果开头和结尾有“,”的话就去掉
String s9 = "2heladfoj545542dada1";
String s = s9.replaceAll("\\d", ",").replaceAll("^,|,$", ""); //正则表达式
System.out.println(s9);  //2heladfoj545542dada1
System.out.println(s);  //heladfoj,,,,,,dada
  • 判断字符串是否全部由数字组成
boolean matches = s1.matches("\\d+");
System.out.println(matches); //false
  • 判断是否为某地区被电话
String tel = "0349-1234567";
boolean matches1 = tel.matches("0349-\\d{7,8}");//后面跟了 7、8 位数字
System.out.println(matches1); //true
  • split 切分

  • String -> char [ ]

char[] chars = s1.toCharArray();
System.out.println(Arrays.toString(chars));
  • 将 char 型数组转为 String
char[] ch1 = new char[]{'h', 'e', 'l', 'l', 'o'};
String ss = new String(ch1);
System.out.println(ss);
  • String 转换为 byte[ ]
String str = "abc123汉字";
byte[] bytes = str.getBytes();//默认采用UTF-8
System.out.println(Arrays.toString(bytes));
byte[] gbks = str.getBytes("gbk"); //采用gbk编码格式
System.out.println(Arrays.toString(gbks));

StringBuilder

在Java8,String、StringBuilder、StringBuffer 等的底层实现都是字节数组 char [] value

三者区别:

String、StringBuffer、StringBuilder 的区别

  • String:底层 final 的,不可变的字符序列

  • StringBuffer:底层非 final 的,可变的字符序列,线程安全,但是效率偏低

  • StringBuilder:底层非 final 的,可变的字符序列,效率高,但是线程不安全

上述三者的共同点是:java8 之前包括 8,他们的底层实现都是的字符数组 char [ ],在java9以及之后的版本中改为了 byte [] 数组;

StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类

三者的效率:

StringBuilder > StringBuffer > String

  1. 操作少量的数据: 适用 String
  2. 单线程操作字符串缓冲区下操作大量数据: 适用 StringBuilder
  3. 多线程操作字符串缓冲区下操作大量数据: 适用 StringBuffer

扩容问题:StringBuffer 类无参构造创建一个长度大小为 16 的 char 型数组,如果添加不下,那么就需要将原来的数组空充为原来的 2 倍 + 2,同时会将原有的数组复制到新的数组当中去

建议使用 StringBuffer 类中的有参构造 指定大小 容量 StringBuffer(int capacity)

常用基本功能

  • 增 append
  • 删 delete
  • 改 replace
  • 查 indexOf
  • 插 insert
  • 长度 length
  • 遍历 toString( ) \ for 循环 +charAt( )

互相转换:

String --> StringBuffer、StringBuilder :直接调用他们的构造器 String 类型传参即可,反之亦然

也可以通过 toString 来转换

public class StringBufferTest {    
    public static void main(String[] args) {
        StringBuffer s1 = new StringBuffer("abc");    
        System.out.println("长度为:" + s1.length());//3 
        System.out.println(s1);    
        s1.append("def");      
        System.out.println("长度为:" + s1.length());//6   
        s1.insert(2, "123");//在指定位置(非索引)之后插入指定字符串     
        System.out.println(s1);   
        s1.replace(2, 5, ""); //替换指定位置之后的指定字符串 左闭右开区间    
        System.out.println(s1);     
        s1.delete(3, 4);     //删除指定位置之后的字符串 左闭右开区间   
        System.out.println(s1);   
        s1.reverse(); //当前字符串翻转    
        System.out.println(s1); //indexOf() 查询字符第一次出现位置的索引         
        //返回索引区间内的一个子字符串 左开右闭
        String substring = s1.substring(0, 3);       
        System.out.println(substring);     
        String s3 = "abc";     
        StringBuffer stringBuffer = new StringBuffer(s3);   
        System.out.println(stringBuffer);     
        StringBuffer stringBuffer1 = new StringBuffer("def");    
        String s = stringBuffer1.toString();   
        System.out.println(s); 
    }
}       

练习

上例子!

String s1 = "abc";
String s2 = "abc";

String s3 = new String("abc");
String s4 = new String("abc");

System.out.println(s1 == s2); // true 
System.out.println(s1 == s3); // false
System.out.println(s3 == s4); // false

拼接字符串

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	只要有一个值是来自于变量的,那么拼接结果就会存在于堆中,在堆空间中 new 一块空间出来
System.out.println(s3 == s6); // false
System.out.println(s3 == s7); // false
System.out.println(s5 == s6); // false
System.out.println(s5 == s7); // false
System.out.println(s6 == s7); // false
posted @ 2022-01-10 14:48  atroot  阅读(54)  评论(0编辑  收藏  举报