String类和String类常用方法

目录

一、String类的重要性

二、认识String类

1.String类的组成​编辑

2.字符串的不可变性

2.1 final

三、字符串的构造

四、String对象的比较

1. ==比较是否引用同一个对象

2. boolean equals(Object anObject) 方法:按照字典序比较

 3. int compareTo(String s) 方法: 按照字典序进行比较

4. int compareToIgnoreCase(String str) 方法:与compareTo方式相同,但是忽略大小写比较

五、字符串查找

1.char charAt(int index) 获取字符串下标的字符

2.int indexOf(int ch) 获取字符第一次出现的下标

3.int indexOf(int ch, int fromIndex) 从指定位置查找ch第一次出现的位置

4.int indexOf(String str) 返回字符串第一次出现的位置

5.int indexOf(String str, int fromIndex)指定位置向后查找s字符串第一次出现的位置 

 6.int lastIndexOf(int ch) 从后往前找第一次出现的字符

7.int lastIndexOf(int ch, int fromIndex) 从指定位置往前找字符第一次出现的位置

8.int lastIndexOf(String str) 从后往前找,返回字符串第一次出现的位置

9.int lastIndexOf(String str, int fromIndex)从指定位置往前找字符串第一次出现的位置

六、转化

1. 数值和字符串转化

2. 大小写转换

3. 字符串转数组

4. 格式化

七、字符串的替换

1.String replaceAll(String regex, String replacement) 替换字符串中所有指定字符

2.String replaceFirst(String regex, String replacement) 替换首个字符

八、字符串拆分

1.String[] split(String regex) 将字符串全部拆分

2.String[] split(String regex, int limit) 将字符串以指定的格式,拆分为limit组

九、字符串截取

1.String substring(int beginIndex) 从指定位置截取到结尾

2.String substring(int beginIndex, int endIndex) 截取指定区域内容

十、其他操作

1.String trim() 去掉字符串中的左右空格,保留中间空格


一、String类的重要性

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

而且在面试题中也频繁用到处理字符串的题目。String、StringBuff和StringBulider之间的区别等。

二、认识String类

1.String类的组成

可以看到String类底层是这4个属性组成。这里我们主要讲一下value。

那么可以发现虽然java中有String类代表字符串类型,但是他底层仍然是以数组存储。value数组里面存放着每一个字符对应的ASII码值

2.字符串的不可变性

2.1 final

  1. 被final修饰的类,不能被继承。“断子绝孙了”
  2. 被final修饰的方法,不能被重写
  3. 被final修饰的变量,变量的值不能修改
  4. 被final修饰的引用,其对应的引用 不能指向其他(引用/对象),但是指向引用的值是可以更改的。

被final修饰的引用,不可改变指向的(引用 / 对象)。但是我们看到array[0] = 10;没有报错,也就是元素不受影响。

看一下这个内存图,final实际修饰的是array指向的地址,把他作为常量。那为什么value数组还是不可以改变呢?

我们看Java源码对String类加上了final,只是String类不能被继承了。但对于改变value数组没有什么关系。即便value数组也加上了final,不能指向新的数组,很多人说是这个原因其实是错误的,因为改变数组里面的值是不受影响的。

真正对String对象不能改变的原因是:

凡是对String有改变的方法,都是对一个新的String进行操作,最后返回一个新改变后的String对象,类似对一个副本操作,最后直接用副本了。这是设计Sting时就已经写好了的。

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

三、字符串的构造

创建字符串的三种方式:

 public static void main(String[] args) {
        //1.使用常量构造方法
        String s1 = "hello";
        System.out.println(s1);

        //new String 对象
        String s2 = new String("hello");
        System.out.println(s2);

        //3.使用字符串构造
        char[] array = {'h','e','l','l','o'};
        String s3 = new String(array);
        System.out.println(s3);
    }

【注意】

1. String是引用类型,内部并不存储字符串本身。

public static void main(String[] args) {
    // s1和s2引用的是不同对象 s1和s3引用的是同一对象
    String s1 = new String("hello");
    String s2 = new String("world");
    String s3 = s1;
    System.out.println(s1.length()); // 获取字符串长度---输出5
    System.out.println(s1.isEmpty()); // 如果字符串长度为0,返回true,否则返回false
    //s1 = "";就代表是0。    s1 = null;在java中并不算是0
}

2. 在Java中“”引起来的也是String类型对象。

// 打印"hello"字符串(String对象)的长度
System.out.println("hello".length());

四、String对象的比较

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
    }

注意:Object类中的equals也是比较的地址

public boolean equals(Object obj) {
        return (this == obj);
}

2. boolean equals(Object anObject) 方法:按照字典序比较

这个equals是String类重写的。比较字符串是否相等

public boolean equals(Object anObject) {
// 1. 先检测this 和 anObject 是否为同一个对象比较,如果是返回true
    if (this == anObject) {
        return true;
    }
// 2. 检测anObject是否为String类型的对象,如果是继续比较,否则返回false
    if (anObject instanceof String) {
    // 将anObject向下转型为String类型对象
        String anotherString = (String)anObject;
        int n = value.length;
    // 3. this和anObject两个字符串的长度是否相同,是继续比较,否则返回false
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
    // 4. 按照字典序,从前往后逐个字符进行比较
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }    
            return true;
        }
    }
    return false;
}
       
public static void main(String[] args) {
    String s1 = new String("hello");
    String s2 = new String("hello");
    String s3 = new String("Hello");
    // s1、s2、s3引用的是三个不同对象,因此==比较结果全部为false
    System.out.println(s1 == s2); // false
    System.out.println(s1 == s3); // false
    // equals比较:String对象中的逐个字符
    // 虽然s1与s2引用的不是同一个对象,但是两个对象中放置的内容相同,因此输出true
    // s1与s3引用的不是同一个对象,而且两个对象中内容也不同,因此输出false
    System.out.println(s1.equals(s2)); // true
    System.out.println(s1.equals(s3)); // false
}

 3. int 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
}

4. int 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
}

五、字符串查找

1.char charAt(int index) 获取字符串下标的字符

char charAt(int index)返回index位置上字符,如果index为负数或者越界,抛出IndexOutOfBoundsException异常
 public static void main(String[] args) {
        String s = "abcdefghi";

        System.out.println(s.charAt(3));//输出d
        System.out.println(s.charAt(-1));//异常
        System.out.println(s.charAt(s.length()+1));//异常

    }

注意:返回值是char类型,如果要用返回值比较必须是char类型

2.int indexOf(int ch) 获取字符第一次出现的下标

int indexOf(int ch)返回ch第一次出现的位置,没有返回-1
    public static void main(String[] args) {
        String s = "aaabbbcccaaabbbccc";
        System.out.println(s.indexOf('c'));//6
        System.out.println(s.indexOf('x'));//-1
    }

3.int indexOf(int ch, int fromIndex) 从指定位置查找ch第一次出现的位置

int indexOf(int ch, int fromIndex)从fromIndex位置开始找ch第一次出现的位置,没有返回-1
 public static void main(String[] args) {
        String s = "aaabbbcccaaabbbccc";
//从6小标往后找第一个出现的位置,输出9
        System.out.println(s.indexOf('a', 6));
//找不到返回-1
        System.out.println(s.indexOf('a', 15));
//比较离谱这个还是能找到,但这肯定是个bug代码,输出0
        System.out.println(s.indexOf('a', -1));
    }

4.int indexOf(String str) 返回字符串第一次出现的位置

int indexOf(String str) 返回str第一次出现的位置,没有返回-1
 public static void main(String[] args) {
        String s = "aaabbbcccaaabbbccc";
        System.out.println(s.indexOf("bb"));//3
    }

5.int indexOf(String str, int fromIndex)指定位置向后查找s字符串第一次出现的位置 

int indexOf(String str, int fromIndex)从fromIndex位置开始找str第一次出现的位置,没有返回-1
 public static void main(String[] args) {
        String s = "aaabbbcccaaabbbccc";
        System.out.println(s.indexOf("bb",10));//12
        System.out.println(s.indexOf("bb",15));//找不到返回-1
        System.out.println(s.indexOf("bb",-100));//比较离谱这个还是能找到,但这肯定是个bug代码
    }

 6.int lastIndexOf(int ch) 从后往前找第一次出现的字符

int lastIndexOf(int ch)从后往前找,返回ch第一次出现的位置,没有返回-1
    public static void main(String[] args) {
        String s = "aaabbbcccaaabbbccc";
        System.out.println(s.lastIndexOf('a'));//输出11
        System.out.println(s.lastIndexOf('x'));//找不到返回-1
    }

7.int lastIndexOf(int ch, int fromIndex) 从指定位置往前找字符第一次出现的位置

int lastIndexOf(int ch, int fromIndex)从fromIndex位置开始找,从后往前找ch第一次出现的位置,没有返 回-1
public static void main(String[] args) {
        String s = "aaabbbcccaaabbbccc";
        System.out.println(s.lastIndexOf('a',6));//从后往前找,输出2
        System.out.println(s.lastIndexOf('x',6));//找不到返回-1
        System.out.println(s.lastIndexOf('a',-1));//bug代码,返回-1
}

8.int lastIndexOf(String str) 从后往前找,返回字符串第一次出现的位置

int lastIndexOf(String str) 从后往前找,返回str第一次出现的位置,没有返回-1
    public static void main(String[] args) {
        String s = "aaabbbcccaaabbbccc";
        System.out.println(s.lastIndexOf("aa"));//10

    }

9.int lastIndexOf(String str, int fromIndex)从指定位置往前找字符串第一次出现的位置

int lastIndexOf(String str, int fromIndex)从fromIndex位置开始找,从后往前找str第一次出现的位置,没有返 回-1
   public static void main(String[] args) {
        String s = "aaabbbcccaaabbbccc";
        System.out.println(s.lastIndexOf("aa",6));//从后往前找
        System.out.println(s.lastIndexOf("xx",6));//找不到返回-1
        System.out.println(s.lastIndexOf("aa",-1));//bug代码返回-1

    }

六、转化

1. 数值和字符串转化

    public static void main(String[] args) {
        String s1 = String.valueOf(1234);
        String s2 = String.valueOf(12.34);
        String s3 = String.valueOf(true);
        String s4 = String.valueOf(new Student("Hanmeimei", 18));

        System.out.println(s1);//1234
        System.out.println(s2);//12.34
        System.out.println(s3);//true
        System.out.println(s4);//Student{name='Hanmeimei', age=18}

        // 字符串转数字
        int data1 = Integer.parseInt("1234");
        double data2 = Double.parseDouble("12.34");
        System.out.println(data1);//1234
        System.out.println(data2);//12.34

    }

2. 大小写转换

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

3. 字符串转数组

 public static void main(String[] args) {
        String s = "hallo";

        char[] ch = s.toCharArray();//转为数组
        for (int i = 0; i < ch.length; i++) {
            System.out.print(ch[i]);//一个字符一个字符的输出,hallo
        }
        System.out.println();

        String s1 = new String(s);//转为字符串
        System.out.println(s1);//hallo
 }

4. 格式化

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

七、字符串的替换

1.String replaceAll(String regex, String replacement) 替换字符串中所有指定字符

 public static void main(String[] args) {
        String str = "helloworld" ;
        System.out.println(str.replaceAll("l", "_"));//he__owor_d
        System.out.println(str.replaceAll("a", "b"));//helloworld
 }

2.String replaceFirst(String regex, String replacement) 替换首个字符

    public static void main(String[] args) {
        String str = "helloworld" ;
        System.out.println(str.replaceFirst("l", "_"));//he_loworld
        System.out.println(str.replaceFirst("a", "b"));//helloworld

    }

注意事项: 由于字符串是不可变对象, 替换不修改当前字符串, 而是产生一个新的字符串.

八、字符串拆分

可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串

1.String[] split(String regex) 将字符串全部拆分

 public static void main(String[] args) {
        String str = "hallo world hallo world";
        String[] result1 = str.split(" ");//将字符串以自定义符号拆分
        for (String s :result1) {
            System.out.println(s);
            //hallo
            //world
            //hallo
            //world
        }
  
}

2.String[] split(String regex, int limit) 将字符串以指定的格式,拆分为limit组

    public static void main(String[] args) {
        String str = "hallo world hallo world";
        String[] result2 = str.split(" ",3);//将字符串以自定义符号,拆分成几份
        for (String s : result2) {
            System.out.println(s);
            //hallo
            //world
            //hallo world
        }
    }

拆分是特别常用的操作. 一定要重点掌握. 另外有些特殊字符作为分割符可能无法正确切分, 需要加上转义.

代码示例: 拆分IP地址

String str = "192.168.1.1" ;
String[] result = str.split("\\.") ;
for(String s: result) {
    System.out.println(s);
}

注意事项:

1. 字符"|","*","+"都得加上转义字符,前面加上 "\\" .

2. 而如果是 "\" ,那么就得写成 "\\\\" .

3. 如果一个字符串中有多个分隔符,可以用"|"作为连字符.

 代码示例: 多次拆分

    public static void main(String[] args) {
        String str = "name=laijdawa&name=dwadwadwa";
        //name=laijdawa   name=dwadwadwa
        String[] s1 = str.split("&");
       for (String s : s1) {
           String[] ss = s.split("=");
           for (String x : ss) {
               System.out.println(x);
           }
       }
    }

结果:

九、字符串截取

从一个完整的字符串之中截取出部分内容。可用方法如下:

1.String substring(int beginIndex) 从指定位置截取到结尾

    public static void main(String[] args) {
        String str = "abcdefg";
        System.out.println(str.substring(2));//cdefg
        System.out.println(str.substring(str.length() + 1));//报错
        System.out.println(str.substring(-1));//报错
    }

2.String substring(int beginIndex, int endIndex) 截取指定区域内容

在JAVA中凡是输入区域的,都是左闭右开:[ , )

    public static void main(String[] args) {
        String str = "abcdefg";
        System.out.println(str.substring(2, 5));//[2,5)左闭右开cde
        System.out.println(str.substring(-1, 5));//报错
        System.out.println(str.substring(0, str.length()+1));//报错
    }

十、其他操作

1.String trim() 去掉字符串中的左右空格,保留中间空格

public static void main(String[] args) {
        String str = "   hallo  world  ";
        System.out.println(str);
        System.out.println(str.trim());//去掉字符串左右两边的空格
}

trim 会去掉字符串开头和结尾的空白字符(空格, 换行, 制表符等).

最好提醒一下大家,String类中的字符串是不可变的,要对其进行改变,其实都是创建了一个新的String类并返回。这会大大降低程序运行效率,所有推荐大家使用StringBuff和StringBulider。之后博主会写一篇StringBuff和StringBulider的博客出来,那就关注一下期待一下后续吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值