Java回顾——字符串

今天来说说字符串。
其实上一篇Java回顾里说了一些关于字符串的东西,比如说字符串池,引用等等,今天详细的说一下字符串这个东西。
首先字符串,也就是Java里常说的String这个东西,是一个最终类,就是不能被继承的类,是一个引用数据类型:

//这是Java中字符串类的定义(当然,没copy它实现的接口)
public final class String{...}

这是首先要明确的,它是一个最终类,是一个引用数据类型。

如何创建字符串:

1、不使用new的方式:

//数据类型 变量名 = 变量值(一般用双引号括起代表字符串)
String prompt = "Hello World";

2、使用new的方式:

//数据类型 变量名 = new关键字 数据类型(变量值)
String prompt = new String("Hello World");//调用String类中的构造方法

两种有什么区别呢?
不使用new的方式,字符串创建在字符串池中;
使用new的方式,字符串在字符串池和堆内存中都创建;
注意:使用new的方式创建的字符串优先使用堆内存中的对象。

字符串的不变性

字符串的不变性是指字符串一旦创建,任何方法都不能修改其内容。
举个例子:

String s = "abc";
s = "abcd";

这并不是说“abc”变成了“abcd”,而是变量s里存的地址变了,第一行它指向字符串“abc”,第二行指向字符串“abcd”,字符串“abc”还是存在的。这就是我为什么一直强调String是引用数据类型的原因。
另外呢,可能还有这样的意思,是对之前字符串创建的补充:
不使用new创建的时候,会先在字符串池中查找,如果该字符串存在,则将该字符串地址赋给变量,如果不存在,则创建,在字符串池中不会有重复的字符串,创建好的字符串也不会被修改,变得只是变量的引用,而不是字符串内容。

字符串的常用操作

1、字符串拼接:
//方式一:+
String s1 = "Hello "+"World";
//方式二:concat()方法
String s2 = "Hello ".concat("World");

最终拼接的结果都是“Hello World”,当然,使用方式二的时候我们常常是用变量。

2、字符串比较:

一般是两种方式:
(1)==:比较两个字符串的地址,相等为true不等为false
(2)equals方法:比较两个字符串的内容,相等为true不等为false
(2.5)equalsIgnoreCase方法:忽略大小写比较字符串内容是否相等
举个例子:

//不使用new方式创建字符串:
String s1 = "Hello";
//使用new方式创建字符串:
String s2 = new String("Hello");
//使用两种方式比较并打印比较结果
System.out.println(s1 == s2);//false
System.out.println(s1.equals(s2));//true

为什么呢?上面说了,==是比较地址,是字符串池中的地址,而使用new方式创建的字符串会优先使用堆内存中的对象;而equals方法比较内容,就相等了,都是Hello。
我们看一下equals方法:

//公有 返回布尔值 传入参数是个Object类型的参数
public boolean equals(Object anObject) {
		//this代表调用者,比较调用者和传入参数是否相等
        if (this == anObject) {
            return true;
        }
        //向下转型前的判断,被比较的是否是String类型
        if (anObject instanceof String) {
         	//把传入参数从Object类型转为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;
 }

之前说了,==比较的是地址,而使用new方法创建的字符串优先使用的是堆内存中的对象,那有没有一个方法让它返回字符串池中的实例呢?有:

//不使用new方式创建字符串:
String s1 = "Hello";
//使用new方式创建字符串:
String s2 = new String("Hello");
//使用两种方式比较并打印比较结果
System.out.println(s1 == s2);//false
System.out.println(s1 == s2.intern());//true

intern()方法:返回字符串池的实例。

我们再看个例子:

String s1 = "hello";
String s2 = " world";
String s3 = "hello world";
String s4 = s1 + s2;
System.out.println(s1 == s4);//false

我们看到,都是不使用new的创建方式,但是为什么最后s1和s4的地址不相等呢?
我们就要深入的了解一下字符串拼接了:

字符串的拼接过程,实际上是通过建立一个StringBuffer,然后调用StringBuffer的append方法,最后再将StringBuffer转为字符串。

即 String s4 = s1 + s2;这一步的时候,s4指向的是s1和s2通过StringBuffer拼接后转成的字符串,这是一个字符串对象,存在堆内存中。

StringBuffer 和 StringBuilder

StringBuffer 和 StringBuilder 是专门用来拼接字符串的类:
StringBuffer是线程安全的,相对而言执行效率低;
StringBuilder是非线程安全的,相对而言执行效率高。
常用的方法:
append():添加
insert():插入
delete():删除
reverse():反转
toString():将StringBuilder/StringBuffer对象转为字符串对象。

//创建StringBuffer对象
StringBuffer sb = new StringBuffer();
//调用append方法,添加Hello
sb.append("Hello");
//StringBuffer对象转为字符串对象
String s = sb.toString();

今天关于字符串就写这么多,里面还有一些方法比如说取子串substring()、查找子串indexOf()等等,包括StringBuffer里面的插入方法和删除方法也没有写例子演示,因为这些直接查API就可以知道用法,甚至IDE工具自动联想功能都可以看出来怎么用,就没有多写,关于Java回顾系列还是想写一些可能会忽略掉或者理解性的东西。

谢谢观看,欢迎各位大佬批评指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值