【Java基础】字符串相关的类

String类

  • java.lang.String
  • String类代表字符串,使用一对""引起来表示;
  • Java程序中的所有字符串字面值都作为此类的实例实现;
  • String内部定义了final char[] value用于存储字符串数据;
  • 字符串是常量,一旦被赋值,就不能改变;
  • String类是final类,不可被继承;
  • String实现了Serializable接口:表示字符串是支持序列化的;
  • String 实现了Comparable接口:表示String可以比较大小;

String类的不可变性

体现在执行以下操作时,需要重写指定内存区域赋值,不能使用原有的value进行赋值

  • ① 当对字符串重新赋值时
  • ② 当对现有的字符串进行连接操作时
  • ③ 当调用String的replace()方法修改指定字符或字符串时

String对象创建的内存图

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

字符串内容为空和字符串对象为空的区别

String s1 = "";
String s2 = null;
System.out.println("isEmpty:" + s1.isEmpty());
//报错 NullPointerException
//s2对象不存在,不能调用方法,空指针异常
System.out.println("isEmpty:" + s2.isEmpty());

String类实例化方式的区别

  • 通过字面量定义的方式:创建了一个对象
  • 通过new + 构造器的方式:创建了两个对象
    字符串常量池中有一个对象,堆中有一个字符串对象;
//此时的s1和s2的数据"hello"声明在方法区中的字符串常量池中
String s1 = "hello";   //创建了一个对象
String s2 = "hello";

//此时的s3和s4保存的是数据在堆空间中开辟空间以后对应的地址值
String s3 = new String("hello");   //创建了两个对象
//一个是堆空间中new结构,另一个是char[]对应的常量池中的数据:"hello"
String s4 = new String("hello");  

//==:对于基本类型,比较的是值是否相同;
//    对于引用类型,比较的是地址值是否相同;
System.out.println(s1 == s2);   //true
System.out.println(s1 == s3);   //false
System.out.println(s1 == s4);   //false
System.out.println(s3 == s4);   //false

//equals:只能比较引用类型,默认也是比较地址值是否相同;
//而String类重写了equals()方法,比较的是内容是否相同;
System.out.println(s1.equals(s3));   //true

Person p1 = new Person("Tom",12);
Person p2 = new Person("Tom",12);
System.out.println(p1.name == p2.name);   //true

字符串的拼接问题

常量与常量的拼接结果在常量池,且常量池中不会存在相同内容的常量;
只要其中有一个是变量,拼接结果就在堆中;
如果拼接的结果调用intern()方法,返回值就在常量池中;

//在字符串常量池中创建了一个字面量为"hello"的字符串
String s1 = "hello";
//在字符串常量池中创建了一个字面量为"world"的字符串
String s2 = "world";
//在字符串常量池中创建了一个字面量为"helloworld"的字符串
String s3 = "helloworld";
//s4指向字符串常量池中已经存在的"helloworld"字符串
String s4 = "hello" + "world";
//在堆空间中创建了一个新的字符串"helloworld"
String s5 = s1 + "world";
//在堆空间中创建了一个新的字符串"helloworld"
String s6 = "hello" + s2;
//在堆空间中创建了一个新的字符串"helloworld"
String s7 = s1 + s2;
//将字符串常量池中已经存在的"helloworld"字符串返回给s8
String s8 = s7.intern();

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 == s6);   //false
System.out.println(s5 == s7);   //false
System.out.println(s6 == s7);   //false
System.out.println(s3 == s8);   //true

String类的常用方法

1)判断:
boolean equals(Object obj):比较字符串的内容是否相同,区分大小写;
boolean equalsIgnoreCase(String str):比较字符串的内容是否相同,忽略大小写;
boolean contains(String str):判断大字符串中是否包含小字符串;
boolean startsWith(String str):判断字符串是否以某个指定的字符串开头;
boolean endsWith(String str):判断字符串是否以某个指定的字符串结尾;
boolean isEmpty():判断字符串是否为空;

(2)获取:
int length():获取字符串的长度;
char charAt(int index):获取指定索引位置的字符;
int indexOf(int ch):返回指定字符在此字符串中第一次出现处的索引;
int indexOf(String str):返回指定字符串在此字符串中第一次出现处的索引;
int indexOf(int ch,int fromIndex):返回指定字符在此字符串中从指定位置后第一次出现处的索引;
int indexOf(String str,int fromIndex):返回指定字符串在此字符串中从指定位置后第一次出现处的索引;

(3)转换:String类的valueOf方法可以把任意类型的数据转成字符串;
static String valueOf(char[] chs):把字符数组转成字符串;
static String valueOf(int i):把int类型的数据转成字符串;
byte[] getBytes():把字符串转换为字节数组;
char[] toCharArray():把字符串转换为字符数组;
String toLowerCase():把字符串转成小写;
String toUpperCase():把字符串转成大写;
String concat(String str):把字符串拼接;

(4)截取:
String substring(int start):从指定位置开始截取字符串,默认到末尾;
String substring(int start,int end):从指定位置开始到指定位置结束截取字符串;

(5)替换:
String replace(char old,char new)
String replace(String old,String new)6)去除字符串两空格:
String trim()7)按字典顺序比较两个字符串:
int compareTo(String str)
int compareToIgnoreCase(String str)

StringBuffer类 / StringBuilder类

  • java.lang.StringBuffer / java.lang.StringBuilder
  • 均代表可变的字符序列,而且提供相关功能的方法也一样;
  • 很多方法与String相同,可以对字符串内容进行增删,此时不会产生新的对象;
  • 作为参数传递时,方法内部可以改变值;
  • value没有final声明,value可以不断扩容;

StringBuffer的构造方法

StringBuffer类不同于String,其对象必须使用构造器生成;

  • StringBuffer():无参构造方法,初始容量为16的字符串缓冲区
  • StringBuffer(int size):构造指定容量的字符串缓冲区对象
  • StringBuffer(String str):指定字符串内容的字符串缓冲区对象

源码分析

//char[] value = new char[0];
String str = new String();
//char[] value = new char[]{'a','b','c'};
String str1 = new String("abc");

//char[] value = new char[16];
StringBuffer sb1 = new StringBuffer();
System.out.println(sb1.length())
sb1.append('a');   //value[0] = 'a';
sb1.append('b');   //value[1] = 'b';

//char[] value = new char["abc".length() + 16];
StringBuffer sb2 = new StringBuffer("abc");
System.out.println(sb2.length());   //3

扩容问题
如果要添加的数据底层数组盛不下了,那就需要扩容底层的数组;
默认情况下,扩容为原来容量的2倍 + 2,同时将原有数组中的元素复制到新的数组中;
开发中推荐使用:StringBuffer(int capacity) 或 StringBuilder(int capacity);

StringBuffer类的常用方法

1)添加 append(xxx)
StringBuffer append(String str):可以把任意类型数据添加到字符串缓冲区里面;
(2)插入 insert(int offset, xxx)
StringBuffer insert(int offset,String str):在指定位置把任意类型的数据插入到字符串缓冲区里面;
(3)删除 delete(int start,int end)
StringBuffer deleteCharAt(int index):删除指定位置的字符;
StringBuffer delete(int start,int end):删除从指定位置开始指定位置结束的内容;
(4)替换
StringBuffer setCharAt(int n,char ch):替换指定位置的字符;
StringBuffer replace(int start,int end,String str):从start开始到end用str替换;
(5)查找 
char charAt(int index):获取指定索引位置的字符;
(6)遍历
for() + charAt() / toString()6)反转
StringBuffer reverse()7)截取:返回值类型是String类型,本身没有发生改变;
String substring(int start):从指定位置开始截取字符串,默认到末尾;
String substring(int start,int end):从指定位置开始到指定位置结束截取字符串;
(8)其他
public int length():返回长度(字符数),实际值;
public int capacity():返回当前容量,理论值;

String 和 StringBuffer 的相互转换

String 转换为 StringBuffer :

// String -- StringBuffer
String str = "hello";

// 方式1:通过构造方法
StringBuffer sb = new StringBuffer(str);
System.out.println("sb:" + sb);

// 方式2:通过append()方法
StringBuffer sb2 = new StringBuffer();
sb2.append(str);
System.out.println("sb2:" + sb2);

StringBuffer 转换为 String :

// StringBuffer -- String
StringBuffer sb = new StringBuffer("world");

// 方式1:通过构造方法
String str = new String(sb);
System.out.println("str:" + str);

// 方式2:通过toString()方法
String str2 = sb.toString();
System.out.println("str2:" + str2);

把数组拼接成一个字符串

public static void main(String[] args) {
    // 定义一个数组
    int[] arr = {11, 22, 33, 44, 55};
    
   // 方式1:用String做拼接的方式
   String s1 = arrayToString(arr);
   System.out.println("s1:" + s1);
      
   // 方式2:用StringBuffer做拼接的方式
   String s2 = arrayToString2(arr);
   System.out.println("s2:" + s2);
}

方式1:用String做拼接的方式:

// 用String做拼接的方式
public static String arrayToString(int[] arr) {
    String s = "";
    s += "[";
    for (int x = 0; x < arr.length; x++) {
        if (x == arr.length - 1) {
            s += arr[x];
        } else {
            s += arr[x];
            s += ", ";
        }
    }
    s += "]";
    return s;
}

方式2:用StringBuffer做拼接的方式:

// 用StringBuffer做拼接的方式
public static String arrayToString2(int[] arr) {
    StringBuffer sb = new StringBuffer();
    sb.append("[");
    for (int x = 0; x < arr.length; x++) {
        if (x == arr.length - 1) {
            sb.append(arr[x]);
        } else {
            sb.append(arr[x]).append(", ");
        }
    }
    sb.append("]");
    return sb.toString();
}

面试题:StringBuffer 和 String 的区别

  • StringBuffer长度和内容可变,String不可变;
  • 如果使用StringBuffer做字符串的拼接,不会浪费太多的资源;

面试题:StringBuffer 和 数组 的区别

  • 二者都可以看出是一个容器,装其他的数据;
  • 但是StringBuffer的数据最终是一个字符串数据;
  • 而数组可以放置多种数据,但必须是同一种数据类型的;

面试题:String、StringBuffer、StringBuilder 的区别

三者底层都使用char[]存储;
三者的效率从高到低排列:StringBuilder > StringBuffer > String;

  • String(JDK1.0):不可变字符序列;
  • StringBuffer(JDK1.0):可变字符序列,同步的,效率低,线程安全;
  • StringBuilder(JDK 5.0):可变字符序列,不同步的,效率高,线程不安全;

注意:作为参数传递的话,方法内部String不会改变其值,StringBuffer和StringBuilder会改变其值;

字符串的常见案例

(1)模拟用户登录
(2)字符串的遍历
(3)统计字符串中大写,小写及数字字符的个数
(4)把字符串的首字母转成大写,其他小写
(5)统计大串中小串出现的次数
(6)把int数组拼接成一个指定格式的字符串
(7)字符串的拼接
(8)字符串的反转
(9)判断一个字符串是否对称

发布了75 篇原创文章 · 获赞 49 · 访问量 3570
App 阅读领勋章
微信扫码 下载APP
阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术工厂 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览