String类:
首先要知道String是对象,不是简单的数据类型,不是int,或者long之类的简单数据类型,他和你自定义的数据对象Object一样,真实值是存放在堆内存里面的。
自己看到的都只是一个引用。
=====================================================================
-----------public int compareTo(String anotherString);------------
String s = "hallo"; String s2 = "ha"; String s3 = "haeeo"; int a = s.compareTo(s2); System.out.println("a:"+a); int b = s.compareTo(s3); System.out.println("b:"+b); int c = s2.compareTo(s3); System.out.println("c:"+c); |
程序输出: a:3 b:7 c:-3 |
s和s2相比,前两个相同,如果是这种情况,则直接返回length1-length2
s和s3相比,前两个相同,不用管,直接用第三个字符的ASCII码做差就行了。所以'l'-'e'=7
s2和s3相比,同第一种情况一样,只是length1比length2小,因此值为负数。
=====================================================================
-----------public String replace(char oldChar, char newChar)---------
--------public String replaceAll(String regex, String replacement)------
前者参数为两个字符串,用newChar替换原串里的所有oldChar。
后者从第一个参数可以看出,需要替换的东西可以用正则表达式描述。
String s = "hello world"; String s1 = s.replace("l", "d"); System.out.println(s1); String s2 = "a78e5opx587"; String s3 = s2.replaceAll("[0-9]", "");//用空串替换原串里所有的0-9的数字 System.out.println(s3); |
输出: heddo wordd aeopx |
=====================================================================
--------------------public native String intern();--------------------
String s = new String("abc"); String s1 = "abc"; String s2 = "abc"; String s3 = s.intern(); System.out.println(s == s3);//false System.out.println(s1 == s3);//true |
s3 = s.intern()这句,当调用s.intern()这句的时候,先去字符串常量池中找,是否有abc这个串,如果没有,则新增,同时返回引用,如果有,则返回已经存在的引用,此处s1和s2都指向常量池中的abc对象,所以此处是存在的,调用s.intern()后,s3和s1、s2指向同一个对象,所以s1==s3返回的是true。
intern()做到了一个很不寻常的行为:在运行期动态的在方法区创建对象,一般只有像new关键字可以在运行期在堆上面创建对象,所以此处比较特殊。属于及时编译的概念。
一般常见的字符串处理函数就这些,其它的还有很多,就不一一列举。
=====================================================================
----------------String类的hashcode和equals方法--------------------
String s2 = s1+"b" 内部是这样实现的:String s2 = new StringBuilder(s1).append("b").toString();所以是在堆上来分配的==比较的是他们的地址,s1+"b"会产生一个新的串,所以和s和s2用==比,返回false,如果用equals的话,返回肯定是true,因为equals()比较的是对象的内容(String类是这样的)。至于hashCode,是这样的:如果没有重写Object的hashCode(),那么如果对象调用equals()放回true,则这两个对象调用hashCode()后返回的整数一定相等。此处继续补充:对于Object类而言,
原生的equals()方法,必须两个对象的地址和内容都一样才返回true,同时Object类原生的hashCode()是参照对象的地址和内容根据一定的算法生产的。所以原生的hashCode()只有调用equals()返回true才相等。而String类不同,String类重写了Object的equals(),放松了条件,只要对象地址或者内容相等就返回true。
String类重写了hashCode()方法,只要内容相等,则调用hashCode返回的整数值也相等,所以此处:s3和s2虽然地址不等,但是内容相等,所以会有:s2.hashCode() == s3.hashCode()返回true。但是这句话反过来讲就不一定成立了,因为毕竟hashCode()只是一种算法。
继续补充:刚刚说了Object类和String类,此处补充下Integer类:Integer类,返回的哈希码就是Integer对象里所包含的那个整数的数值,例如Integer a=new Integer(50),则a.hashCode的值就是50 。由此可见,2个一样大小的Integer对象,返回的哈希码也一样。
StringBuffer和StringBuilder:
二者几乎没什么区别,基本都是在调用父类的各个方法,一个重要的区别就是StringBuffer是线程安全的,内部的大多数方法前面都有关键字synchronized,这样就会有一定的性能消耗,StringBuilder是非线程安全的,所以效率要高些。
-----------------public synchronized int length()-----------------
-----------------public synchronized int capacity()-------------------
二者都是获取字符串的长度,length()获取的是当前字符串的长度,capacity()获取的是当前缓冲区的大小。
StringBuffer sb = new StringBuffer(); 使用StringBuffer()时,默认开辟16个字符的长度的空间。System.out.println(sb.length());; System.out.println(sb.capacity()); |
输出: 0 16 |
使用public StringBuffer(String paramString)时,开辟paramString.length+16大小的空间。 StringBuffer sb = new StringBuffer("hello"); System.out.println(sb.length());; System.out.println(sb.capacity()); |
输出: 5 21 |
StringBuffer sb = new StringBuffer("hello"); StringBuffer sb2 = new StringBuffer("hello"); System.out.println(sb.equals(sb2));//false 虽然equals比较的是内容,但是那是在String类里面重写后equals方法,StringBuffer里面没有重写equals方法,所以只能在内容和地址都相同的情况下才能返回true。 |
--------------public synchronized void trimToSize()------------------
该方法用于将多余的缓冲区空间释放出来。
StringBuffer sb = new StringBuffer("hello erqing"); System.out.println("length:"+sb.length()); System.out.println("capacity:"+sb.capacity()); sb.trimToSize(); System.out.println("trimTosize:"+sb.capacity()); |
输出: length:12 capacity:28 trimTosize:12 |