String类基础方法详解

字符串

一.String类

  • String对象是不可变的
  • String类中每一个看起来会修改String值的方法,实际上都是创建了一个全新的String对象,以包含修改后的字符串内容,而最初的String对象丝毫未动

1.String对象的比较

在比较String对象的时候,不能单纯的用==来比较两个字符串的大小,这样比较的是他们的堆地址 ,在比较两个字符串的时候,要用到String类提供的equals方法,它的返回值是boolean类型
下面看一段示例:

	String str1 = "i love you";
	String str2 = "i hate you";
	System.out.println(str1.equals(str2));  //equals函数的返回值为Boolean类型

这段代码的输出结果为false;

  • 小知识:在今后的开发中,如果要判断用户输入的字符串是否等同于特定字符串,一定要将特定字符串写在前面,避免用户输入的字符串为空导致出错;(看如下例子)

            String str2 = null;
            System.out.println(str2.equals("hello"));
    

    会出现以下错误:Exception in thread “main” java.lang.NullPointerException

2.重载“+”与StringBuilder

因为字符串(String对象)是不可变的,所以在对字符串进行拼接时,将会产生大量垃圾空间(虽然java系统会在底层自动优化),带来一定的效率问题;

在进行字符串的拼接时,编译器其实自主使用了StringBuilder类,创建一个StringBuilder对象,用以构造最终的String,并用每个字符串调用一次StringBuilder的append()方法。最后调用toString方法来生成结果。

这样也许你会觉得反正编译器会自主优化成StringBuilder对象,但学过汇编的可以进入到底层源码中查看,会发现尽管这样,当使用拼接次数过大时,还是会产生效率问题;

3.String的匿名对象

  • 在任何语言的底层,都不会提供有直接的字符串类型。现在所谓的字符串只是高级语言提供给用户方便开发的支持而已。在java中,所有使用 “ ” 定义的内容本质上来讲都是String的匿名对象。
  • 例如:String str = “ i love you ” ;这条语句中的 “ i love you ” 就是String的一个匿名对象,我们可以通过“ i love you ” 加点(.)来调用String类的各种方法,这进一步说明了“ i love you ”是一个对象;

4.String的两种实例化格式以及他们的区别

String类有两种实例化格式,如下所示:

        String str1 = "hello";   //直接实例化   方法一
        String str2 = new String("hello");   //方法二

我们来看方法一的特点:

String str1 = "hello";
String str2 = "hello";
String str3 = "hello";
System.out.println(str1 == str2);
System.out.println(str2 == str3);
System.out.println(str1 == str3);

这段代码将会输出:
true
true
true

  • 这说明了直接实例化的字符串一样时,他们都在同一块堆内存中保存,如下图:

1549801471448

  • String类的设计使用了共享设计模式
  • 在JVM底层实际上会自动维护一个对象池(字符串对象池),如果现在采用了直接赋值的模式进行String类的对象 实例化操作,那么该实例化对象(字符串内容)将自动保存到这个对象池之中。如果下次继续使用直接赋值的模式 声明String类对象,此时对象池之中如若有指定内容,将直接进行引用;如若没有,则开辟新的字符串对象而后将 其保存在对象池之中以供下次使用
    所谓的对象池就是一个对象数组(目的就是减少开销);

下面看看方法二:

String str = new String("hello");

这条语句在内存中分布如下图:
1549802542459

通过如上图可见,通过构造方法实例化就会产生两块堆内存空间,并且一块为垃圾空间(没有引用指向的堆空间为垃圾空间 )。

观察下面一段代码:(字符串共享问题)

        String str1 = "hello";
        String str2 = new String("hello");   //该字符串常量没有保存到对象池中
        System.out.println(str1 == str2);   //输出false

代码输出:false

为了解决这一问题,在String类中提供有方法入池操作:public String intern();
如下代码:

        //入池操作
        String str1 = new String("hello").intern();
        //str1 = str1.intern();   //或者这样写,记住intern()方法有返回值哟,为String;
        String str2 = "hello";
        System.out.println(str1 == str2);

注意:intern()方法返回值为String,所以注释那一句不要写成:str1 . intern( ) ;

5.字符与字符串

  • 字符串就是一个字符数组,所以String类中有转换为字符数组的方法;
方法名称 类型 描述
1 public String(char value[] ) 构造 将字符数组中所有内容变为字符串
2 public String (char value[],int offset,int count) 构造 将部分字符数组中的内容变为字符串
3 public char charAt(int index) 普通 取得指定索引位置的字符,索引从0开始
4 public char[] toCharArray() 普通 将字符串变为字符数组返回

看下面一段练习代码,输出答案已在注释上

        //字符串--->数组
        String str1 = "i love you";
        char[] arr = str1.toCharArray();
        for(char x:arr){    //foreach语句
            System.out.print(x+"、");    //i、 、l、o、v、e、 、y、o、u、
        }
        //数组--->字符串
        System.out.println(new String(arr)); //i love you
        System.out.println(new String(arr,2,5)); //love

6.字符串比较常用方法

方法名称 类型 描述
1 public boolean equals(object anObject) 普通 区分大小写的比较
2 public boolean equalsIgnoreCase(String anotherString) 普通 不区分大小写的比较
3 public int compareTo(String anotherString) 普通 比较两个字符串的大小关系
  • 方法一和方法二就不用多介绍,**对于方法三, ** 这是一个非常重要的方法 ,它的返回值是一个整型,规则如下:
    相等时:返回0;
    小于:返回内容小于0;
    大于:返回内容大于0;

看下面这段关于compareTo()方法 的练习代码,来具体认识它:

        String str1 = "hEllo";
        String str2 = "kello";
        System.out.println(str1.compareTo(str2));  //-3
        System.out.println("A".compareTo("a"));   //-32
        System.out.println("b".compareTo("a"));   //1
  • 从上面这段代码可以看出,返回的数值是字符在ASCII表上对应的差值,所以compareTo()是一个可以区分大小写的方法,是String类中非常重要的一个方法。

7.字符串查找

关于字符串查找有如下方法:

方法名称 类型 描述
1 public boolean contains(CharSequence s) 普通 判断一个子字符串是否存在
2 public int indexOf(String str) 普通 从头开始查找指定字符串的位置,查到了返回位置的开始索引,如果查不到返回 -1
3 public int indexOf(String str,int fromIndex) 普通 从指定位置开始查找子字符串的位置
4 public int lastIndexOf(String str) 普通 由后向前查找子字符串的位置
5 public int lastIndexOf(String str,int fromIndex) 普通 由指定位置由后向前查找
6 public boolean startsWith(String prefix) 普通 判断是否以指定字符串开头
7 public boolean startWith(String prefix,int toffset) 普通 从指定位置开始判断是否以指定字符串开头
8 public boolean endsWith(String suffix) 普通 判断是否以指定字符串结尾

8.字符串替换

方法名称 类型 描述
1 public String replaceAll(String regex,String replacement) 普通 替换所有指定内容
2 public String replaceFirst(String regex,String replacement) 普通 替换首个内容

9.字符串拆分

方法名称 类型 描述
1 public String[] split(String regex) 普通 将字符串全部拆分
2 public String[] split(String regex,int limit) 普通 将字符串部分拆分,该数组长度就是limit极限

注意:

  • 有些内容无法正常拆分的时候,需要用到“\\”转义, 例如拆分IP地址;
  • 拆分IP地址和多次拆分 ⭐以后在开发中会经常遇到,特别是多次拆分;

练习代码如下:

        //拆分IP地址
        String str = "123.45.67.8";
        String[] arr = str.split("\\.");
        for (String x:arr) {
            System.out.println(x);
        }

输出:
123
45
67
8

        //多次拆分
        String str = "Bob:19|Alice:20";
        String[] result = str.split("\\|");
        for (int i = 0; i < result.length; i++) {
            String[] temp = result[i].split(":");
            System.out.println(temp[0]+"="+temp[1]);
       }

输出:
Bob=19
Alice=20

10.字符串截取

方法名称 类型 描述
1 public String substring(int beginIndex) 普通 从指定索引截取到结尾
2 public String substring(int beginIndex,int endIndex) 普通 截取部分内容

11.其他常用方法

方法名称 类型 描述
1 public String toUpperCase() 普通 字符串转大写
2 public String toLowerCase() 普通 字符串转小写
3 public int length() 普通 取得字符串长度
4 public String trim() 普通 去掉字符串中的左右空格,保留中间空格

字符串是最普遍最常用的,熟练掌握它的各种用法,才会在开发中不再细枝末叶上耗费时间!

二.StringBuffer类

  • StringBuffer类与String类最大的区别就在于:String的内容不可修改,而StringBuffer的内容可以修改
  • StringBuffer修改字符串使用append方法;
  • 除了append方法,StringBuffer还有一些String类没有的方法,例如字符串反转方法:reverse();

练习代码:

        StringBuffer sb = new StringBuffer();
        sb.append("hello").append("world").append("\n").append("haha");
        System.out.println(sb);

输出:
helloworld
haha

  • 面试宝典:
    StringBuffer、String、StringBuilder的区别是什么?

    • String内容不可修改,StringBuffer和StringBuider内容可修改;
    • StringBuffer采用同步处理,属于线程安全操作;而StringBuilder采用异步处理,属于线程不安全操作;

猜你喜欢

转载自blog.csdn.net/eternal_yangyun/article/details/87207290