关于String类必须了解的

1.为什么要有String类

在C语言中要表示字符串只能使用字符数组或者字符指针,可以使用标准库提供的字符串系列函数完成大部分操作,但是这种将数据和操作数据方法分离开的方式不符合面相对象的思想,而字符串应用又非常广泛,因此Java语言专门提供了String类。

2.字符串的构造方式

2.1使用常量串构造

        String s1="hello world";
        System.out.println(s1);

2.2直接new String对象

String s2 = new String("hello world");
 System.out.println(s1);

2.3 使用字符数组进行构造

char[] array = {'h','e','l','l','o','w','o','r','l','d'};
 String s3 = new String(array);
 System.out.println(s1);

3.String对象的比较

3.1使用==比较

对于内置类型,比较的是变量中的值;对于引用类型比较的是引用中的地址。

public static void main(String[] args) {
 int a = 10;
 int b = 20;
 int c = 10;
 // 对于基本类型变量,==比较两个变量中存储的值是否相同
 System.out.println(a == b); // false
 System.out.println(a == c); // true
 // 对于引用类型变量,==比较两个引用变量引用的是否为同一个对象
 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
}

3.2使用equals方法比较(按照字典序比较)

String类重写了父类Object中equals方法,Object中equals默认按照==比较,String重写equals方法后按字典序比较字符串的内容。

public static void main(String[] args) {
 String s1 = new String("hello");
 String s2 = new String("hello");
 String s3 = new String("Hello");
 System.out.println(s1.equals(s2)); // true
 System.out.println(s1.equals(s3)); // false
}

equals比较:String对象中的逐个字符
虽然s1与s2引用的不是同一个对象,但是两个对象中放置的内容相同,因此输出true
s1与s3引用的不是同一个对象,而且两个对象中内容也不同,因此输出false

3.3使用compareTo(String s)方法(按照字典序比较)

与equals的区别:
equals返回的是boolean类型,而compareTo返回的是int类型。
具体比较方式:

  1. 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值
  2. 如果前k个字符相等(k为两个字符长度最小值),返回值两个字符串长度差值
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
}

3.4使用 compareToIgnoreCase(String str) 方法(与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
}

4.字符串查找方法

方法功能
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
    public static void main(String[] args) {
        String s="aabbbcccddaa";
        System.out.println(s.charAt(1));//a
        System.out.println(s.indexOf('b'));//2
        System.out.println(s.indexOf("ccc"));//5
        System.out.println(s.indexOf("aa",4));//10
        System.out.println(s.indexOf('a',9));//10
        System.out.println(s.lastIndexOf('a'));//11
        System.out.println(s.lastIndexOf("aa"));//10
    }

5.字符串的转化

5.1数值和字符串转化

1.数字转字符串

    public static void main(String[] args) {
        String s1=String.valueOf(123);
        String s2=String.valueOf(12.34);
        System.out.println(s1);
        System.out.println(s2);
    }

2.字符串转数字

    public static void main(String[] args) {
        int a=Integer.parseInt("123");
        int b=Integer.parseInt("12.34");
        System.out.println(a);
        System.out.println(b);
    }

5.2字符串大小写转化

public static void main(String[] args) {
 String s1 = "hello";
 String s2 = "HELLO";
 // 小写转大写
 System.out.println(s1.toUpperCase());
 // 大写转小写
 System.out.println(s2.toLowerCase());
}

5.3字符串转数组

public static void main(String[] args) {
 String s = "hello";
 // 字符串转数组
 char[] ch = s.toCharArray();
 for (int i = 0; i < ch.length; i++) {
 System.out.print(ch[i]);
 }
 System.out.println();
 // 数组转字符串
 String s2 = new String(ch);
 System.out.println(s2);
}

5.4格式化控制

public static void main(String[] args) {
 String s = String.format("%d-%d-%d", 2019, 9,14);
 System.out.println(s);
}

6.字符串常量池

为了使程序的运行速度更快、更节省内存,Java为8种基本数据类型和String类都提供了常量池。
字符串常量池在JVM中是StringTable类,实际是一个固定大小的HashTable(一种高效用来进行查找的数据结构)不同JDK版本下字符串常量池的位置以及默认大小是不同的:

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

下面用代码说明

        public static void main(String[] args) {
            String s1="hello";
            String s2="hello";
            String s3=new String("hello");
            System.out.println(s1==s2);//true
            System.out.println(s1==s3);//false
        }

从输出结果可以看出s1和s2引用的是同一个对象,原因就是在类加载时,字节码文件中的字符串常量会被保存在字符串常量池中。而s3指向的是new 的新对象,所以s1和s3不同。
String的构造函数

    public String(String original) {
        this.value = original.value;//    String 的成员,value为字符数组的引用
        this.hash = original.hash;//默认为0
    }
 

在这里插入图片描述

7.intern方法

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

public static void main(String[] args) {
 char[] ch = new char[]{'a', 'b', 'c'};
 String s1 = new String(ch); // s1对象并不在常量池中
 //s1.intern(); // s1.intern();调用之后,会将s1对象的引用放入到常量池中
 String s2 = "abc"; // "abc" 在常量池中存在了,s2创建时直接用常量池中"abc"的引用
 System.out.println(s1 == s2);
}
// 输出false
// 将上述方法打开之后,就会输出true
  1. String str = “hello”
    只会开辟一块堆内存空间,保存在字符串常量池中,然后str共享常量池中的String对象
  2. String str = new String(“hello”)
    会开辟两块堆内存空间,字符串"hello"保存在字符串常量池中,然后用常量池中的String对象给新开辟的String对象赋值。
  3. String str = new String(new char[]{‘h’, ‘e’, ‘l’, ‘l’, ‘o’})
    先在堆上创建一个String对象,然后利用copyof将重新开辟数组空间,将参数字符串数组中内容拷贝到String对象中

7.字符串的不可变性

1.String类在设计时就是不可改变的,String类实现描述中已经说明了。
2. 所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象
3. 为什么 String 要涉及成不可变的?(不可变对象的好处是什么?)

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

StringBuilder和StringBuffer

7.1 StringBuilder和StringBuffer的介绍

由于String的不可更改特性,为了方便字符串的修改,Java中又提供StringBuilder和StringBuffer类。这两个类大部分功能是相同的,这里介绍 StringBuilder常用的一些方法.

方法说明
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)从start开始一直到末尾的字符以String的方式返回
String substring(int start,int end)将[start, end)范围内的字符以String的方式返回
StringBuffer reverse()反转字符串String toString() 将所有字符按照String的方式返回

StringBuilder比StringBuffer效率更高,但StringBuffer是线程安全的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值