String类

String类

String类是Java中的字符串类型,它是引用类型

三种常用的字符串构造

java 复制代码
public class Test {
    public static void main(String[] args){
        String str1 = "hello";
        String str2 = new String("hello");
        char[] array = {'h','e','l','l','o'};
        String str3 = new String(array);
    }
}

其中str1的写法是str2的简化版,注意这里不涉及常量池的概念,后文会引入常量池重新画图

练习

使用equals比较字符串的值是否相同

使用comparaTo方法比较俩个字符串的大小

java 复制代码
public class Test {
    public static void main(String[] args) {
        String str1 = "hello";
        String str2 = "hello";
        int ret = str1.compareTo(str2);
        if(ret > 0 ){
            System.out.println("s1>s2");
        }else if(ret<0){
            System.out.println("s1<s2");
        }else {
            System.out.println("s1==s2");
        }
    }
}

关于comparaTo方法,之前的文章有详细的介绍

字符串查找的方法

char charAt(int index) 返回Index位置上字符

遍历字符串"hello"中的每一个字符

java 复制代码
public static void main(String[] args) {
        String str = "hello";
        for (int i = 0; i < str.length(); i++) {
            System.out.printf(str.charAt(i)+" ");
        }
    }

int indexOf(char ch) **找到字符串中第一个出现ch的位置下标,**如果没找到就返回-1

java 复制代码
   public static void main(String[] args) {
        String str = "hello";
        System.out.println(str.indexOf('l'));
    }

int indexOf(char ch,int index) 从字符串中index位置开始找,找到第一次出现ch的下标

java 复制代码
  public static void main(String[] args) {
        String str = "hello";
        System.out.println(str.indexOf('l',3));
    }

int indexOf(String str)在字符串str1中找字符串 str并返回其下标

java 复制代码
public static void main(String[] args) {
        String str = "abdegababcge";
        System.out.println(str.indexOf("abc"));
    }

String[] args

字面上就是一个名为args的字符串数组,运行时命令行参数 ,通过命令行输入的参数就会传入到这个数组中

字符串转换

String.valueOf(各种类型)

java 复制代码
    public static void main(String[] args) {
        int a = 123;
        int b = 456;
        String str1 = String.valueOf(a);
        String str2 = String.valueOf(b);
        System.out.println(a+b);
        System.out.println(str1+str2);
    }

其它类型转换成字符串,类型的包装类.parse类名(字符串)

java 复制代码
 public static void main(String[] args) {
        String str = "123";
        int a = Integer.parseInt(str);
        System.out.println(a+1);
    }

toUpperCase 把字符串中的小写字母变成大写

java 复制代码
 public static void main(String[] args) {
        String str = "abcdef123";
        String str2 = str.toUpperCase();
        System.out.println(str2);
    }

toCharArray 把字符串改成字符数组

java 复制代码
public static void main(String[] args) {
        String str = "abcdef";
        char[] array = str.toCharArray();
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i]+" ");
        }
    }

字符串拆分

String[] split(依据的分隔符)

java 复制代码
    public static void main(String[] args) {
        String str = "zhangsan&wangwu";
        String[] strings = str.split("&");
        for (int i = 0; i < strings.length; i++) {
            System.out.println(strings[i]);
        }
    }

如果又多个分隔符 可以用 **'|"**隔开

java 复制代码
  public static void main(String[] args) {
        String str = "name=zhangsan&age=18";
        String[] strings = str.split("=|&");
        for (int i = 0; i < strings.length; i++) {
            System.out.println(strings[i]);
        }
    }

字符串截取

String substring(int begain,int end)

java 复制代码
 public static void main(String[] args) {
        String str = "hello";
        System.out.println(str.substring(1,4));
    }

trim() 出除去字符串中左右俩边的空格

java 复制代码
 public static void main(String[] args) {
        String str = "    hello  world   ";
        System.out.println(str);
        System.out.println(str.trim());
    }

字符串常量值(底层是StringTable的哈希表)

首先看如下代码

java 复制代码
    public static void main(String[] args) {
        String str1 = "hello";
        String str2 = "hello";
        String str3 = new String("hello");
        String str4 = new String("hello");
        System.out.println(str1 == str2);
        System.out.println("--------------------");
        System.out.println(str3 == str4);
        System.out.println("--------------------");
        System.out.println(str1 == str3);
        System.out.println("--------------------");
        System.out.println(str1 == "hello");
        System.out.println("--------------------");
        System.out.println(str3 == "hello");
    }

结果

你知道是什么原因吗?

java 复制代码
String str1 = "hello";

如果是这种直接用双引号引起来,没有New,会先检查常量池(String Table)有没有字符串常量"hello" ,**如果没有就把"hello"放入到常量池中,如果常量池中已经有"hello"了,就直接指向这个常量池中的"hello",**这里是在常量池中放入了一个"hello"

java 复制代码
String str2 = "hello";

和刚刚一样,会先检查常量池有没有"hello",很显然,这次常量池中有"hello",此时就直接指向这个常量池中的"hello"

因此str1==str2,它们指向同一个地址(引用)

而str3 和 str4,是自己New了一个引用指向常量池的"hello",因此又是一个新的地址.所以str3 和 str4不指向同一个地址,str1和str3的地址当然也是不一样的

String3 = new String("hello"),这里有俩步(如果常量池没有"hello"的话),第一步把hello放入常量池,第二步重申请一个空间再指向常量池中的"hello"

同样用双引号引起来的就是常量池中的字符串(如果有直接指向,没有就放入),因此这里的str1会等于"hello",而str3指向的不是常量池中的"hello",因此它们的地址不相等

intern(),手动把字符串放到常量池中

字符串不可变

String里面的value数组是private类型, 外界无法访问到,因此字符串是不可以被修改的,当然value数组类也被final修饰,指向也不可以改变,而String类同样也被final修饰,意味着这个类不可以被继承

StringBuilder 和 StringBuffer

字符串拼接

现在让字符串去拼接1w个数,看看它的执行效率

java 复制代码
public static void main(String[] args) {
        String str = "abcd";
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            str += i;
        }
        long end = System.currentTimeMillis();
        System.out.println(end-start);
    }

执行结果:

字符串在实现拼接的时候,其实是利用StringBuilder拼接的,虽然这个代码看上去没有StringBuilder,但是背后是用到的,它等价于如下代码

java 复制代码
public static void main(String[] args) {
        String str = "abcd";
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder = stringBuilder.append(str);
            stringBuilder = stringBuilder.append(i);
            str = stringBuilder.toString();
        }
        long end = System.currentTimeMillis();
        System.out.println(end-start);
    }

可以看到字符串在拼接 的时候,是先创建一个StringBuilder对象,再利用这个对象的append方法去拼接字符串,最后在使用toString方法把结果给原先的字符串

根据上述代码,我们可以把StringBuilder的创建放在for循环外面,这样在拼接过程中就只创建了一次SrtingBuilder对象,再把StringBuilder的对象的结果给原先字符串也拿出for循环

java 复制代码
  public static void main(String[] args) {
        String str = "abcd";
        long start = System.currentTimeMillis();
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < 10000; i++) {
            stringBuilder = stringBuilder.append(str);
            stringBuilder = stringBuilder.append(i);
        }
        str = stringBuilder.toString();
        long end = System.currentTimeMillis();
        System.out.println(end-start);
    }

可以看到效率提升非常明显

Strinig StringBuilder StringBuffer的区别

String中的value数组被private修饰 ,且value数组被final修饰不可以改变指向该数组的引用, 同样String类也被final修饰,String类不可以被继承..因此String类是不可以被修改的 ,我们修改的字符串最后返回的都是一个新的引用

StringBuilder 和 StringBuffer在单线程下没有太大区别 ,StringBuilder和StirnfBuffer是可以被修改的,返回的是它们本身 ....StringBuffer中的方法被synchronized 修饰,给该方法加锁,一般用在多线程场景下,保证线程安全.

相关推荐
小薛博客8 分钟前
22、Jenkins容器化部署Java应用
java·运维·jenkins
西贝爱学习12 分钟前
如何在 IntelliJ IDEA 中进行全局替换某个字段(或文本)
java·ide·intellij-idea
南部余额16 分钟前
Spring 基于注解的自动化事务
java·spring·自动化
alf_cee16 分钟前
通过Idea 阿里插件快速部署java jar包
java·ide·intellij-idea
坚持每天敲代码30 分钟前
【教程】IDEA中导入springboot-maven工程
java·maven·intellij-idea
CodeCraft Studio38 分钟前
国产化PDF处理控件Spire.PDF教程:如何在 Java 中通过模板生成 PDF
java·python·pdf·spire.pdf·java创建pdf·从html创建pdf
阿方.9181 小时前
《数据结构全解析:栈(数组实现)》
java·开发语言·数据结构
YC运维1 小时前
Ansible题目全解析与答案
java·算法·ansible
程序员清风1 小时前
贝壳一面:年轻代回收频率太高,如何定位?
java·后端·面试
考虑考虑1 小时前
Java实现字节转bcd编码
java·后端·java ee