String类

字符串是常量,创建后不能改变

 public static void main(String[] args) {
        String name = "Hello";

        name = "zhangsan";
    }

当我这样创建了一个name为“Hello”的时候,给name赋了这个值,

这时候栈里的String name 指向的是Hello

当我把super赋值给name的,这时候,就不再指向Hello了,改成指向zhangsan,但是Hello并没有消失,没有东西指向它的时候,会被JVM识别为垃圾,然后回收掉,这也就是创建了之后不能改变。

字符串字面值存储在字符串池中,可以共享

根据上面的知识点再结合下面这张图就会看的很清晰

String类_String类

当我创建一个String name2 = "zhangsan" 的时候,就回去会去字符串池里找,如果有,就会指向它


另一种创建String对象的方法

String str = new String ("Java是世界上最好的编程语言");

这时候创建了一个对象,那么就代表再堆里创建了一个“Java是世界上最好的编程语言”,但是在字符串池里也有一个“Java是世界上最好的编程语言”,在Java编译的时候其实指向的是堆里的,但是堆里的对象指向的也是字符串池里的,所以不用担心字符串池里的字符浪费空间。

回顾上面的知识点

String str1 = new String ("123");
String str2 = new String ("123");
System.out.print(str1 == str2);

这样返回的肯定是false,当你创建这两个对象的时候,在堆里就创建了两个不一样的对象,这就是在Java基础学的时候,字符串比较使用的equals方法,而不是 ==

常用方法

1、public int length():

返回字符串长度

String str = "Java是世界上最好的编程语言";
System.out.println(str.length());

返回结果为15


2、public char charAt(int index):

根据传进来的下标获取字符

String str = "Java是世界上最好的编程语言";
System.out.println(str.charAt(str.length()-1));  //charAt是从下标0开始查找的,所以需要-1

charAt()里面我传入str的长度-1的意思就是获取str的最后一个值,当我们不知道最后一位是多少位的时候就可以这样使用;


3、public boolean contains (String str):

判断当前字符串是否包含str

String str = "Java是世界上最好的编程语言";
System.out.println(str.contains("Java"));	//true
System.out.println(str.contains("php"));	//false

4、public char[] toCharArray():

将字符串转换为数组

String str = "Java永远的神,Java真香";

System.out.println(Arrays.toString(str.toCharArray()));

不写Arrays.toString()的输出结果和输出这个字符串没啥区别


5、public int indexOf(String str):

查找str首次出现的下标,存在则返回下标;不存在则返回-1;

String str = "Java是世界上最好的Java编程语言,Java真香";
System.out.println(str.indexOf("Java"));
//输出结果0

第二种查找方法:从哪里开始查找

如果我有多个Java,那我要查第一个之后的怎么办呢?

String类_String类_02

这个方法可以在后面加个逗号,选择从第几个下标开始查询。

String str = "Java是世界上最好的Java编程语言,Java真香";
System.out.println(str.indexOf("Java",4));
//结果为11,下标从0开始

6、public int lastIndexOf(String str):

查询字符串在当前字符串中最后一次出现的下标索引

System.out.println(str.lastIndexOf("Java"));

7、public String trim():

去掉字符串前后的空格

String me = " Hello World ";
System.out.println(me.trim());

String类_String类_03

输出结果会去除前后的空格,但中间的不会

System.out.println(me.replaceAll(" +",""));

这一段代码可以去除掉所有的空格


8、public String toUpperCase():

将小写转换成大写

System.out.println(me.toUpperCase());

String类_String类_04


9、public boolean endWith(String str):

判断字符串是否为str结尾

String str = "Java是世界上最好的Java编程语言,Java真香";
System.out.println(str.endsWith("真香"));

10、public String raplace(char oldChar, char newChar):

将就字符串替换为新字符串

String say = "Hello World";
System.out.print(say.raplace("World" , "Java"))

这样就能成功把World替换成Java,输出结果就是Hello Java


11、public String[] split(String str):

根据str做拆分

String say = "Java is the best programing language";

//这时候我们的需求是把每一个单词拆分开
String [] s = say.split(" ");	//方法里传入的是空格,就是说遇到空格就拆分

 for(String string : s){
     System.out.println(string);
 }

但如果我在代码里添加了逗号怎么办呢?

很简单,这里有一个小技巧

say.split("[ ,]");

在方法里传入一个空格,在里面敲一个空格和逗号,这样就能拆分空格和逗号了,需要拆分其他的在逗号后面加就行了

这时候又出现了新的问题:我如果里面一行有很多空格怎么办呢?

简单

say.split("[ ,]+");

在后面添加一个+号,emmm ,至于为什么,有待深究~


12、public boolean equalsIgnoreCase(String anotherString):

字符串比较忽略大小写

String s1 = "HELLO";
String s2 = "hello";
//这样的两个字符串使用equals方法比较必定是false,因为HashCode值不一样	

//但是这样使用忽略大小写的方式就可以返回为true
System.out.println(s1.equalsIgnoreCase(s2));

13、public int compareTo(String anotherString):

字符串比较大小

String name1 = "abc";
String name12 = "abcdefgh";
System.out.println(name1.compareTo(name12));

案例演示

要求:

已知String str = "this is a text";

1. 将str中的单词单独获取出来
2. 将str中的text替换成practice
3. 在text前面插入一个easy
4. 将每个单词的首字母大写
package com.simple.javaChangYongType.demo04;

/**
 * @author huYuHao
 * @version 1.0
 * @create 2021/4/13
 * @since 1.8
 */
public class Test {
    public static void main(String[] args) {
        String str = "this is a text";

        //将str的单词单独获取出来
        System.out.println("将str的单词单独获取出来");
        String[] s = str.split(" ");
        for ( String string : s){
            System.out.println( string);
        }
        System.out.println("===========================");

        //将test替换成practice
        System.out.println("将test替换成practice");
        System.out.println(str.replace("text","practice"));
        System.out.println("===========================");

        //在test前面加easy
        System.out.println("在test前面加easy");
        System.out.println(str.replace("text","easy test"));
        System.out.println("===========================");

        //把str的首字母变成大写
        System.out.println("把str的首字母变成大写");
        for(int i = 0; i < s.length; i++){
            char c = s[i].charAt(0);
            //把第一个字母变成大写
            char c1 = Character.toUpperCase(c);
            String s2 = c1+s[i].substring(1);
            System.out.print(s2 + " ");
        }

    }
}

可变字符串

StringBuffer:

可变字符串,jdk1.0提供,运行效率慢,但是线程安全

 StringBuffer sb = new StringBuffer();
sb.append("java世界第一");
System.out.println(sb.toString());
sb.append("java真香");
System.out.println(sb.toString());

//2、insert 添加
sb.insert(0, "卢本伟牛逼");
System.out.println(sb.toString());

//3、replace:指定位置替换
sb.replace(0, 5, "美食界老八");
System.out.println(sb.toString());

//4、delete:删除字符串
sb.delete(0,5);
System.out.println(sb.toString());

//删除全部,-1是为了不让字符串看起来啥都没有
sb.delete(0,sb.length()-1);
System.out.println(sb);

StringBuilder:

可变字符串,jdk5.0提供,运行效率快,但是线程不安全

 StringBuilder sb = new StringBuilder();
sb.append("java世界第一");
System.out.println(sb.toString());
sb.append("java真香");
System.out.println(sb.toString());

//2、insert 添加
sb.insert(0, "卢本伟牛逼");
System.out.println(sb.toString());

//3、replace:指定位置替换
sb.replace(0, 5, "美食界老八");
System.out.println(sb.toString());

//4、delete:删除字符串
sb.delete(0,5);
System.out.println(sb.toString());

//删除全部,-1是为了不让字符串看起来啥都没有
sb.delete(0,sb.length()-1);
System.out.println(sb);

和StringBuffer用法一致,所以他们的差别就是Buffer安全性强,但是速度慢

Builder虽然快,但是线程不安全。


测试String字符串拼接速度和StringBuffer字符串拼接的速度

首先说明,运行速度不一定每个人都一样

package com.simple.javaChangYongType.demo05;

/**
 * @author huYuHao
 * @version 1.0
 * @create 2021/4/14
 * @since 1.8
 */
public class Demo02 {
    //测试String字符串拼接和StringBuffer拼接的速度
    public static void main(String[] args) {
        //在程序最开始的地方写表示程序运行开始时间
        long start = System.currentTimeMillis();

//        String s = "";
//        for(int i = 0; i < 99999; i++){
//            s += i;
//        } 用时:22313
//        System.out.println(s);
        StringBuffer s = new StringBuffer();
        for(int i = 0; i < 99999; i ++){
            s.append(i);
        }
        System.out.println(s.toString());
        //运行到这里的时候程序就差不多结束了,这个时间减去开始的时间就是运行的时间
        long end = System.currentTimeMillis();
        System.out.println("用时:" + (end - start) );
    }
}