Java String深入理解

来源:互联网 发布:linux tomcat调试模式 编辑:程序博客网 时间:2024/05/20 23:58

String的不可变性

Java中的String具有不可变性,即初始化后既不可更改。这种机制是和Java内存模型紧密关联的。Java中的String,如果不是new出来的对象,是要放在常量池里的,常量池是方法区中的一个区域,作为一个基本数据类型的缓存,值相同的基本数据指向相同的地址。

例如:

String str1="abc";String str2="abc";

str1,str2指向常量池中同一块地址。而new出来的String是需要放在堆中的,例如:String str3=new String("abc");

之所以采用不可变的设计,是基于几点好处:

1,不可变属性先天的线程安全性

2,不改变HashCode,不需要重新计算

3,规避了其他类使用可变String可能带来的风险:
例如Set是一个不可重复的容器,把String放入set再修改String内容可能造成Set包含相同内容。

如何比较两个字符串?使用“==”还是equals()方法?

“==”测试的是两个对象的引用是否相同——地址等。
equals()比较的是两个字符串的值是否相等——值相等。
除非你想检查的是两个字符串是否是同一个对象,否则使用equals()来比较字符串。

PS:intern的概念:http://blog.csdn.net/picway/article/details/60748823

为什么针对安全保密高的信息,char[]比String更好?

因为String是不可变的,就是说它一旦创建,就不能更改了,直到垃圾收集器将它回收走。而字符数组中的元素是可以更改的。这就意味着你就可以在使用完之后将其更改(清空),而不会保留原始的数据。所以使用字符数组的话,安全保密性高的信息(如密码之类的)将不会存在于系统中被他人看到。

高效字符串分割与重组:

用String.split(String regex)方法来做到分割字符。“\s”代表空白字符” “, “\t”, “\r”, “\n”.
用String.join()函数来重组字符串:

示例:

import java.util.LinkedHashSet;import java.util.Set;public class SplitString {    public static void main(String[] args){        String str="I am Wang An Yang";        String[] strArr=str.split("\\s+");        for(int i=0;i<strArr.length;i++){            System.out.println(strArr[i]);        }        System.out.println(String.join(" ",strArr));        //JDK demo        Set<String> strings = new LinkedHashSet<>();        strings.add("Java"); strings.add("is");        strings.add("very"); strings.add("cool");        String message = String.join("-", strings);        System.out.println(message);    }}

输出:

IamWangAnYangI am Wang An YangJava-is-very-cool

String.join()可以重组任意集合类和数组,第一个参数是分割符,第二个参数是集合。
join()的另一个表示:

public static String join(CharSequence delimiter, CharSequence... elements);

示例

import java.util.LinkedHashSet;import java.util.Set;public class SplitString {    public static void main(String[] args){        String message2 = String.join("-", "Java", "is", "cool");        System.out.println(message2);    }}

输出:

Java-is-cool

还可以使用下面说到的StringBuffer和StringBuilder连接字符串。

String vs StringBuilder vs StringBuffer

String vs StringBuilder: StringBuilder是可变的,这意味着它创建之后仍旧可以更改它的值。

StringBuilder vs StringBuffer: StringBuffer是synchronized的,它是线程安全的的,但是比StringBuilder要慢。

在进行字符串连接时,使用StringBuffer和StringBuilder效率比直接String加法效率高,因为在加的过程要把整个字符串复制到新的字符串中。

String[] strs={"abc","def","xyz"};StringBuffer sf=new StringBuffer();for(String s:strs){    sf.append(s);}return sf.toString();//concat all the String into a long String. 
String[] strs={"abc","def","xyz"};String newstr="";for(String s:strs){    newstr=newstr+s;}return newstr;

String +的编译器优化:

String s="a"+"b"+"c"

在编译时会自动编译成String s="abc"存储在栈空间中。

String s=new String("abc");会存储在对空间中。

String s1="a";String s1="b";String s1="c";String s=s1+s2+s3;

这个操作编译器会自动转化成StringBuilder进行字符串拼接,s1,s2,s3,s4,s都存储在堆中。

如何重复一个字符串

在Java中,我们可以使用Apache Commons Lang包中的StringUtils.repeat()方法来重复一个字符串。

String str = "abcd";String repeated = StringUtils.repeat(str,3);//abcdabcdabcd

这个方法可以用StringBuilder自己实现。

如何将字符串转换成时间

String str = "Sep 17, 2013";Date date = new SimpleDateFormat("MMMM d,yy",Locale.ENGLISH).parse(str);System.out.println(date);//Tue Sep 17 00:00:00 EDT 2013

如何计算一个字符串某个字符的出现次数?

请使用apache commons lang包中的StringUtils:

int n = StringUtils.countMatches(“11112222”, “1”);
System.out.println(n);

如何将字符串转化成int?

int n = Integer.parseInt(“10”);

substring()方法到底做了什么?

str.substring(m, n)会通过调用Arrays.copyofRange()方法复制字符数组元素创建一个新的字符数组,用来表示新的字符串。

我们可以针对字符串使用switch条件语句吗?

对于JDK 7,回答是肯定的。

// Java 7或者以后的版本switch (str.toLowerCase()) {      case "a":           value = 1;           break;      case "b":           value = 2;           break;}

String.intern()

String.intern()的是native方法,作用是“如果常量池存在该字符串,则返回字符串,如果常量池不存在字符串,则将该字符串放入到常量池,然后再返回。”对于不同的Java版本,内存操作方面会略有区别,这是因为在JDK7之后,常量池和JavaHeap走向统一,intern不会改变字符串变量的位置,而是在该变量上标记,这个变量是常量池变量了。

详情参考:http://blog.csdn.net/picway/article/details/60748823

转并修改自
https://mp.weixin.qq.com/s?__biz=MjM5NzMyMjAwMA==&mid=2651478518&idx=1&sn=ff63ab280b774c5952048c8114bf209c&chksm=bd2535898a52bc9fbe45caef918e8cf79f47ac887f8494bd35277a7bf4b1a8451760486e0020&mpshare=1&scene=1&srcid=0510TdDPyiBcwRk8Js6lB4v2&pass_ticket=cfe5hW%2Fty%2Fqd6iDzfuEKjJJNrgDtWMlptxXdnYRIUnUI0rOa6YYoXUfgEiasiOJb#rd

0 0