[Java][华为云Java编程创造营][学习笔记][第三阶段][07_Java常用类][01_字符串类分析和使用]

举报
John2021 发表于 2021/12/26 20:02:10 2021/12/26
【摘要】 1,字符串类的分析和使用 1.1,String分析String类的底层使用char的数组保存数据。String类是一个final类,不允许被继承。String类是一个不可变类,该类的对象生成后,内容不会发生改变。String类中的所有返回String类型对象的成员方法都是返回一个新的String对象。 1.2,String比较String类重写了equals方法,用来比较两个字符串的内容是...

1,字符串类的分析和使用

1.1,String分析

  • String类的底层使用char的数组保存数据。
  • String类是一个final类,不允许被继承。
  • String类是一个不可变类,该类的对象生成后,内容不会发生改变。
  • String类中的所有返回String类型对象的成员方法都是返回一个新的String对象。

1.2,String比较

  • String类重写了equals方法,用来比较两个字符串的内容是否相同。
  • String类的equals方法和==做区分,==比较的是两个字符串对象的地址。
public class Test
{
    public static void main(String[] args)
    {
        String s1 = new String("123");
        String s2 = new String("123");
        System.out.println(s1 == s2);//false
        System.out.println(s1.equals(s2));//true
    }
}
  • String类重写了equals方法,从底层代码分析:
public class Test
{
    public boolean equals(Object anObject)
    {
        if (this == anObject)
        {
            return true;
        }
        if (anObject instanceof String)
        {
            String anotherString = (String) anObject;
            int n = value.length;
            if (n == anotherString.value.length)
            {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0)
                {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
}
  • 首先调用==判断两个对象的地址是否相同,如果相同即是同一个对象,内容必定相同则返回true。
  • 如果地址不相同则先判断传入的对象是否是String类的实例,如果不是直接返回false,如果是String类的实例则判断两个字符串的长度是否相等,不相等返回false,如果长度相等的话就挨个比较两个字符串的字符数组,如果有一个不相同的话就返回false,都相同的话返回true。

1.3,字符串类实例化机制

  • Java中String类型的创建有以下两种方式:
    1. 创建的时候,JVM会现在字符串常量池中去查找是否存在该字符串,如果存在直接返回该字符串对象的地址,否则会在常量池中创建该字符串对象并返回地址。

    2. 创建的时候,也会先查找常量池中是否存在该字符串,如果存在就会在堆里面复制一份这个字符串对象,然后把堆里面的对象地址返回给变量;不存在的话就会在堆中和常量池中各创建一个对象,并返回堆中对象的地址。

//第一种方式
String s1 = "hello world";
//第二种方式
String s2 = new String("hello world");
//只在常量池中创建了一个对象,创建了1个对象
String s1 = "123";
//在常量池和堆中各创建了一个对象,创建了2个对象
String s2 = new String("456");

1.4,字符串的维护和参数传递

  • String类的+和concat都可以将2个字符串拼接到一块,形成新的字符串。
  • String的+还可以将字符串和非字符串连接在一起,成为新的字符串,concat不可以与非字符串拼接在一起。
public class Test
{
    public static void main(String[] args)
    {
        String s1 = "123";
        System.out.println(s1 + 123);
        //System.out.println(s1.concat(123));//错误
    }
}
  • String的参数传递
public class Test
{
    public static void test(String str)
    {
        str = "world";
    }

    public static void main(String[] args)
    {
        String str1 = new String("hello");
        test(str1);
        System.out.println(str1);//hello
    }
}
  • 引用str1指向新对象new String(“hello”)。
  • test()刚刚开始调用时,形参str复制了实参str1的值,这个值也就是对象new String(“hello”)的地址,所以这时候引用str和引用str1指向同一个对象"hello"。
  • 进入到test()方法内部,world这个对象被分配给形参str,而这个操作对象实参str1并没有影响,所以这个时候引用str指向"world",而引用str1仍然指向原来的对象"hello"。
  • test()方法结束后,形参str从栈内存中消失,它指向的对象"world"由于没有其他引用指向它,也可以被gc回收了。打印引用str1指向的对象,即"hello"。

1.5,字符串的常用API方法

  • String类的常用方法:

    1. equals方法,用来比较两个字符串内容是否相同。
    2. charAt方法,返回指定索引处的字符。
    3. contains方法,判断字符串中是否包含另一个字符串。
    4. indexOf方法,返回第一次出现某个字符串的位置。
    5. isEmpty方法,判断字符串是否是空字符串。
    6. split方法,将字符串分割,返回一个字符串数组。
    7. trim方法,返回去掉字符串开头和结尾的空格后的字符串。
    8. toCharArray方法,将字符串转换为字符数组。
    9. replace方法,替换原字符串中的某个字符或子字符串,全部替换。
    10. length方法,返回字符串长度。
  • String类的常用方法案例:

public class Test
{
    public static void main(String[] args)
    {
        String string = " hello world!!";
        System.out.println(string.charAt(1));//h
        System.out.println(string.contains("he"));//true
        System.out.println(string.indexOf("e"));//2
        System.out.println(string.isEmpty());//false
        System.out.println(string.split(" ")[0]);//去空格
        System.out.println(string.trim());//hello world!!
        System.out.println(string.toCharArray()[1]);//返回字符数组  h
        System.out.println(string.replace("!", "?"));// hello world??
        System.out.println(string.length());//14
        System.out.println(string.lastIndexOf("!"));//13
    }
}

1.6,StringBuffer类

  • StringBuffer又称为可变字符序列,它是一个类似于String的字符串缓冲区,可以改变该序列的长度和内容。
  • StringBuffer是同步安全的。
public class Test
{
    public static void main(String[] args)
    {
        //public StringBuffer():无参构造方法
        StringBuffer sb = new StringBuffer();
        System.out.println("sb:" + sb);//sb:
        System.out.println("sb.capacity:" + sb.capacity());//sb.capacity:16
        System.out.println("sb.length:" + sb.length());//sb.length:0

        //public StringBuffer(int capacity):指定容量的字符串缓冲区对象
        StringBuffer sb2 = new StringBuffer(50);
        System.out.println("sb:" + sb2);//sb:
        System.out.println("sb.capacity:" + sb2.capacity());//sb.capacity:50
        System.out.println("sb.length:" + sb2.length());//sb.length:0

        //public StringBuffer(String str):指定字符串内容的字符串缓冲区对象
        StringBuffer sb3 = new StringBuffer("hello");
        System.out.println("sb:" + sb3);//sb:hello
        System.out.println("sb.capacity:" + sb3.capacity());//sb.capacity:21
        System.out.println("sb.length:" + sb3.length());//sb.length:5
    }
}

1.7,StringBuilder类

  • StringBuilder类也是字符串缓冲区,非同步安全。
public class Test
{
    public static void main(String[] args)
    {
        String str = new String("abc");
        StringBuilder stringBuilder = new StringBuilder(str);
        System.out.println("使用带参的构造方法生成的字符串缓冲区:" + stringBuilder);
        //输出结果:使用带参的构造方法生成的字符串缓冲区:abc

        //空参构造方法
        StringBuilder builder = new StringBuilder();
        System.out.println("空参构造的字符串缓冲区:" + builder);
        String s1 = builder.toString();

        StringBuilder builder2 = new StringBuilder();
        System.out.println("空参构造的字符串缓冲区:" + builder2);
        String s2 = builder2.toString();

        //equals()
        boolean result1 = builder.equals(builder2);
        System.out.println(result1);//false
        boolean result2 = s1.equals(s2);
        System.out.println(result2);//true
    }
}
  • String、StringBuffer、StringBuilder的区别:
    1. String是内容不可变的。
    2. StringBuffer、StringBuilder都是内容可变的。
    3. StringBuffer是同步的,数据安全,效率低。
    4. StringBuilder是不同步的,数据不安全,效率高。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。