Java学习总结之String类

Java学习总结之String类

1.常用方法

1.1字符串构造

  • 使用常量串进行构造

    String str = "hello world";
    
  • new String对象

    String str = new String("hello world")
    
  • 使用字符数组进行构造

    char[] array={'h','e','l','l','o'};
    String str = new String(array);
    

注意事项

  • String是引用类型,内部并不存储字符串本身
  • 在Java中""引起来的也是String类型对象

1.2String对象的比较

  • ==比较是否引用同一个对象(比较的是对象的地址,内置类型比较的是值)
String s1 = new String("hello");
String s2 = new String("hello");
String s3 = new String("world");
String s4 = s1;
System.out.println(s1 == s2); // false
System.out.println(s2 == s3); // false
System.out.println(s1 == s4); // true
  • equals 方法:按照字典序比较

    String类重写了父类Object中equals方法,Object中equals默认按照==比较。

    String s1 = new String("hello");
    String s2 = new String("hello");
    String s3 = new String("world");
    String s4 = s1;
    System.out.println(s1.equals(s2)); // true
    System.out.println(s2.equals(s3)); // false
    System.out.println(s1.equals(s4)); // true
    
  • comareTo方法:按照字典序顺序比较

    public static void main(String[] args) {
      String s1 = new String("abc");
      String s2 = new String("ac");
      String s3 = new String("abc");
      String s4 = new String("abcdef");
      System.out.println(s1.compareTo(s2)); // 不同输出字符差值-1
      System.out.println(s1.compareTo(s3)); // 相同输出 0
      System.out.println(s1.compareTo(s4)); // 前k个字符完全相同,输出长度差值 -3
    }  
    
  • compareToIgnore方法:与compareTo方式相同,但是忽略大小写比较

    public static void main(String[] args) {
        String s1 = new String("abc");
        String s2 = new String("ac");
        String s3 = new String("ABc");
        String s4 = new String("abcdef");
        System.out.println(s1.compareToIgnoreCase(s2)); 
    	// 不同输出字符差值-1
        System.out.println(s1.compareToIgnoreCase(s3)); 
        // 相同输出 0
        System.out.println(s1.compareToIgnoreCase(s4)); 
        // 前k个字符完全相同,输出长度差值 -3
    }
    

1.3字符串查找

常用的查找方式

方法功能
char charAt(int index)返回index位置上字符,如果index为负数或者越界,抛出 IndexOutOfBoundsException异常
int indexOf(int ch)返回ch第一次出现的位置,没有返回-1
int indexOf(int ch, int fromIndex)从fromIndex位置开始找ch第一次出现的位置,没有返回-1
int indexOf(String str)返回str第一次出现的位置,没有返回-1
int indexOf(String str, int fromIndex)从fromIndex位置开始找str第一次出现的位置,没有返回-1
int lastIndexOf(int ch)从后往前找,返回ch第一次出现的位置,没有返回-1
int lastIndexOf(int ch, int fromIndex)从fromIndex位置开始找,从后往前找ch第一次出现的位置,没有返 回-1
int lastIndexOf(String str)从后往前找,返回str第一次出现的位置,没有返回-1
int lastIndexOf(String str, int fromIndex)从fromIndex位置开始找,从后往前找str第一次出现的位置,没有返 回-1

1.4转化

  • 数值与字符串相互转化

    String s1 = String.valueOf(1234);  //数值转字符串
    int sum = Integer.parseInt(s1);   //字符串转数值
    
  • 大小写转换

    String s1 = "hello";
    String s2 = "HELLO";
    s1.toUpperCase();   //s1 = "HELLO"
    s2.toLowerCase();   //s2 = "hello"
    
  • 字符串转数组

    String s = "hello";
    // 字符串转数组
    char[] ch = s.toCharArray();
    // 数组转字符串
    String s2 = new String(ch);
    
  • 格式化

    String s = String.format("%d-%d-%d", 2022, 8,12);
    System.out.println(s);
    
    //执行结果
    2022-8-12
    

1.5字符串替换

String str = "helloworld" ;
System.out.println(str.replaceAll("l", "-"));
// replaceAll替换指定的所有内容
System.out.println(str.replaceFirst("l", "-"))
//replaceFirst替换指定的首个内容

//执行结果
he--owor-d
he-loworld

1.6字符串拆分

  • 字符串全部拆分

    String str  = "hello world"
    String[] result = str.split(" ") ; // 按照空格拆分
    for(String s: result) {
    	System.out.println(s);
    }
    
    //执行结果
    hello
    world
    
  • 字符串部分拆分

    String str = "hello world hello world" ;
    String[] result = str.split(" ",2) ;
    for(String s: result) {
    	System.out.println(s);
    }
    
    //执行结果
    hello world
    hello world
    

注意事项

  1. 字符"|“,”*“,”+"都得加上转义字符,前面加上 “\” .
  2. 而如果是 “” ,那么就得写成 “\\” .
  3. 如果一个字符串中有多个分隔符,可以用"|"作为连字符

1.7字符串的截取

  • 从指定索引截取到结尾

    String str = "helloworld" ;
    System.out.println(str.substring(5));
    
    //执行结果
    world
    
  • 截取部分内容

    String str = "helloworld" ;
    System.out.println(str.substring(0,5));
    
    //执行结果
    hello
    

注意事项

  1. 注意前闭后开区间的写法, substring(0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标

1.8字符串去掉去掉空格

String str = " hello world " ;
System.out.println("["+str+"]");
System.out.println("["+str.trim()+"]");

//执行结果
[ hello world ]
[hello world]

2.字符串常量池

2.1创建对象方式的不同

当以不同的方式创建字符串的时候:

String str1="hello";
String str2="hello";
String str3=new String("world");
String str4=new String("world");
System.out.println(str1==str2);		//true
System.out.println(str1==str3); 	//false
System.out.println(str3==str4);		//false

可以看到当以以字符常量串创建的时候,创建的字符串的地址一样,而用new String的时候结果的地址是不一样的,简单地说就是str1和str2引用的对象是一样的,而str3和str4不一样。

为了使程序的运行速度更快、更节省内存,Java为8种基本数据类型和String类都提供了常量池。

为了节省存储空间以及程序的运行效率,Java中引入了:

  1. class文件常量池:每个.Java源文件编译后生成.class文件中会保存当前类中的字面常量以及符号信息

  2. 运行时常量池:在.class文件被加载时,.class文件中的常量池被加载到内存中称为运行时常量池,运行时常量池每个类都有一份

  3. 字符串常量池

2.2字符串常量池(String Table)

字符串常量池在JVM中是StringTable类,实际是一个固定大小的HashTable(一种高效用来进行查找的数据结构)不同JDK版本下字符串常量池的位置以及默认大小是不同的

JDK版本字符串常量池位置大小设置
Java6(方法区)永久代固定大小:1009
Java7堆中可设置,没有大小限制,默认大小:60013
Java8堆中可设置,有范围限制,最小是1009

2.3String对象的创建

  • 直接使用字符串常量进行赋值

    String str1="hello";
    String str2="hello";
    System.out.println(str1==str2);		//true
    

    当字节码文件加载的时候字符串hello已经创建好了并且保存在字符串常量池中,当使用常量串赋值的时候优先从字符串常量池找,找到了就将该字符串引用赋值给要赋值的对象。 因此会出现这两个字符串地址一致。

  • 通过new创建String类的对象

    String str3=new String("world");
    String str4=new String("world");
    System.out.println(str3==str4);
    
    1. 当我们用new来创建String对象的时候,由于new的对象是唯一的,所以地址都是不一样的。
    2. 使用常量串创建String类型对象的效率更高,而且更节省空间。用户也可以将创建的字符串对象通过intern方式添加进字符串常量池中。

2.4intern方法

intern是一个native方法(Native方法指:底层使用C++实现的,看不到其实现的源代码),该方法的作用是手动将创建的String对象添加到常量池中。

public static void main(String[] args) {
    char[] ch = new char[]{'a', 'b', 'c'};
	String s1 = new String(); // s1对象并不在常量池中
	//s1.intern(); 
	String s2 = "abc"; // "abc" 在常量池中存在了,s2创建时直接用常量池中"abc"的引用
	System.out.println(s1 == s2);     //false
    char[] ch = new char[]{'q', 'w', 'e'};
	String s3 = new String(); // s3对象并不在常量池中
	s1.intern(); 
	String s2 = "qwe"; // "abc" 在常量池中存在了,s2创建时直接用常量池中"abc"的引用
	System.out.println(s3 == s4);   //true
} 

2.6字符串的不可变性

  • String类在设计时就是不可变性的,String类中的字符实际保存在内部维护的value数组中,该数组被final修饰,表示value自身的值不可变即不能引用其它字符数组,但是其引用空间中的内容可以修改。
  • String类被final修饰,表明该类不能被继承
  • 所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象

不可变的对象的好处:

  1. 方便实现字符串对象池. 如果 String 可变, 那么对象池就需要考虑写时拷贝的问题了.
  2. 不可变对象是线程安全的.
  3. 不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中

3.StringBuffer和StringBuilder

3.1常用方法

方法说明
StringBuff append(String str)在尾部追加,相当于String的+=,可以追加:boolean、char、char[]、 double、float、int、long、Object、String、StringBuff的变量
char charAt(int index)获取index位置的字符
int length()获取字符串的长度
int capacity()获取底层保存字符串空间总的大小
void ensureCapacity(int mininmumCapacity)扩容
void setCharAt(int index, char ch)将index位置的字符设置为ch
int indexOf(String str)返回str第一次出现的位置
int indexOf(String str, int fromIndex)从fromIndex位置开始查找str第一次出现的位置
int lastIndexOf(String str)返回最后一次出现str的位置
int lastIndexOf(String str, int fromIndex)从fromIndex位置开始找str最后一次出现的位置
StringBuff insert(int offset, String str)在offset位置插入:八种基类类型 & String类型 & Object类型数据
StringBuffer deleteCharAt(int index)删除index位置字
StringBuffer delete(int start, int end)删除[start, end)区间内的字符
StringBuffer replace(int start, int end, String str)将[start, end)位置的字符替换为str
String substring(int start,int end)将[start, end)范围内的字符以String的方式返回
String substring(int start)从start开始一直到末尾的字符以String的方式返回
StringBuffer reverse()反转字符串
String toString()将所有字符按照String的方式返回

3.2String类与StringBuilder或StringBuffer类的相互转换

String和StringBuilder类不能直接转换。如果要想互相转换,可以采用如下原则:

  1. String变为StringBuilder: 利用StringBuilder的构造方法或append()方法

    String str = "abc";
    //第一种方法
    StringBuilder stb = new StringBuilder(str);
    //第二种方法
    StringBuilder stb1 = new StringBuilder();
    stb1.append(str);
    
  2. StringBuilder变为String: 调用toString()方法

    StringBuilder stb = new StringBuilder("abc");
    String str = stb.toString();
    

3.3String,StringBuilder和StringBuffer类的异同

  • 相同点:底层都是通过char数组实现的
  • 不同点:
    1. String对象一旦创建,其值是不能修改的,如果要修改,会重新开辟内存空间来存储修改之后的对象;而StringBuffer和StringBuilder对象的值是可以被修改的;
    2. StringBuffer几乎所有的方法都使用synchronized实现了同步,线程比较安全,在多线程系统中可以保证数据同步,但是效率比较低;而StringBuilder 没有实现同步,线程不安全,在多线程系统中不能使用 StringBuilder,但是效率比较高。
    3. 如果我们在实际开发过程中需要对字符串进行频繁的修改,不要使用String,否则会造成内存空间的浪费;当需要考虑线程安全的场景下使用 StringBuffer,如果不需要考虑线程安全,追求效率的场景下可以使用 StringBuilder;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值