java基础-String学习笔记

1、String的不可变性、原因。

我们将一个已有的字符串“abcd”第二次赋值成“abcedl”,不是在原内存地址上 修改数据,而是重新指向一个新地址。

不可变原因:(详见String类源码)

首先String类是用final关键字修饰的,说明String类不能被继承。String类的主要成员变量是一个char[]数组,且被“private”、“final”修饰,所以数组的引用地址不变。而且在String 类的方法中也没有去修改数组中的元素。

不可变性好处:

(1)字符串常量池的使用,内容相同的字符串是指向同一个内存地址的,可以节省空间,提高效率。只有当字符串是不可变的,字符串池才有可能实现。

(2)在并发场景下,对资源做写操作才有危险。不可变对象不能被写,所以线程安全。

(3)因为字符串是不可变的,所以在它创建的时候hashcode就被缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,字符串的处理速度要快过其它的键对象。这就是HashMap中的键往往都使用字符串。

2、String常用方法

(1)int length()  返回此字符串的长度。

(2)boolean equals(Object anObject)  将此字符串与指定的对象比较。

(3)int indexOf(int ch)  返回指定字符在此字符串中第一次出现处的索引。

(4)int indexOf(String str)   返回指定子字符串在此字符串中第一次出现处的索引。

(5)char[] toCharArray()  将此字符串转换为一个新的字符数组。

(6)String toLowerCase()  使用默认语言环境的规则将此 String 中的所有字符都转换为小写。

(7)String toLowerCase(Locale locale)  使用给定 Locale 的规则将此 String 中的所有字符都转换为小写。

(8)String trim()  返回字符串的副本,忽略前导空白和尾部空白。

(9)isEmpty()  判断字符串是否为空。

(10)String substring(int beginIndex, int endIndex)  返回一个新字符串,它是此字符串的一个子字符串。

(11)String replace(char oldChar, char newChar)  返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。

(12)String replaceAll(String regex, String replacement)  使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。

(13)String[] split(String regex, int limit)  根据匹配给定的正则表达式来拆分此字符串。

(14)boolean matches(String regex)  告知此字符串是否匹配给定的正则表达式。

3、面试题

String s1="a"+"b"+"c";
String s2="abc";
System.out.println(s1==s2);  //true
System.out.println(s1.equals(s2));  //true

原因:java 中常量优化机制,编译时 s1 已经成为 abc 在常量池中查找创建,s2 不需要再创建。

 

4、Java:String、StringBuffer 和 StringBuilder 的区别

String:字符串常量,字符串长度不可变。原因同上。

StringBuffer:字符串变量(Synchronized,即线程安全)。如果要频繁对字符串内容进行修改,出于效率考虑最好使用 StringBuffer,如果想转成 String 类型,可以调用 StringBuffer 的 toString() 方法。Java.lang.StringBuffer 线程安全的可变字符序列。在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。可将字符串缓冲区安全地用于多个线程。

StringBuilder:字符串变量(非线程安全)。在内部 StringBuilder 对象被当作是一个包含字符序列的变长数组。

基本原则:

  • 如果要操作少量的数据用 String ;
  • 单线程操作大量数据用StringBuilder ;
  • 多线程操作大量数据,用StringBuffer。

5、String 类中 concat() 方法和 + 号的区别:

pubic class Demo{
    pulic satic void main(String[] args){
        String str1 = "a".concat("b").concat("c");
        String str2 = "a"+"b"+"c";
        String str3 = "abc";
        String str4 = new String("abc");
        System.out.println(str1 == str2); //运行结果为false
        System.out.println(str1 == str3); //运行结果为false
        System.out.println(str2 == str3); //运行结果为ture
        System.out.println(str2 == str4); //运行结果为false
        System.out.println(str1.equals(str4)); //运行结果为true
    }
}

解析:

首先关于 new 出来的对象和 String s = "字符串" 的 == 执行结果为 false 就不多赘述了,因为 == 比较的是两个对象的地址值,equals() 比较的是字面值。那么 concat 方法和 + 号的区别在这里有体现了,我们查看concat方法的源码可以看到,它是通过复制数组在通过 char 数组进行拼接生成一个新的对象,所以地址值会有变动,而 + 号不会。

6、StringBuffer方法

(1)public StringBuffer append(String s)
将指定的字符串追加到此字符序列。

(2)public StringBuffer reverse()
 将此字符序列用其反转形式取代。

(3)public delete(int start, int end)
移除此序列的子字符串中的字符。

(4)public insert(int offset, int i)
将 int 参数的字符串表示形式插入此序列中。

(5)replace(int start, int end, String str)
使用给定 String 中的字符替换此序列的子字符串中的字符。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值