zoukankan      html  css  js  c++  java
  • String、StringBuilder、StringBuffer

    一、String

    1.基本方法

     1 1)length():String中字符的个数。
     2 
     3 2)charAt(int index):取得String中该索引位置上的char。
     4 
     5 3)toCharArray():生成一个char[],包含String的所有字符。
     6 
     7 4)equals():比较两个String的内容是否相同。
     8 
     9 5)compareTo(String anotherString):按词典顺序比较String的内容,比较结果为负数、零或正数。
    10 
    11 6)contains(CharSequence s):如果该String对象包含参数的内容,则返回true。
    12 
    13 7)equalsIgnoreCase():忽略大小写,如果两个String的内容相同,则返回true。
    14 
    15 8)startsWith():返回boolean结果,以表明该String是否以此参数起始。
    16 
    17 9)endsWith(String s):返回boolean结果,以表明此参数是否是该字符串的后缀。
    18 
    19 10)isEmpty():当且仅当length()为0时返回true。
    20 
    21 11)split(String regex):根据给定正则表达式的匹配拆分此字符串。
    22 
    23   或|,点.,加+,乘*,在字符串中出现时,如果这个字符串需要被split,则split时候,需要在前面加两个反斜杠。
    24 
    25       与&,在split时候,不需要转义。
    26 
    27 12)substring(int beginIndex, int endIndex):返回一个新字符串,它是此字符串的一个子字符串。
    28 
    29 13)toLowerCase():转为小写。
    30 
    31 14)toUpperCase():转为大写。
    32 
    33 15)trim():返回字符串的副本,忽略前导空白和尾部空白。
    34 
    35 16)valueOf(char[] data):返回char数组参数的字符串表示形式。
    View Code

    2.不可变性

    java中的不可变类:

    1. 可变类和不可变类(Mutable and Immutable Objects)的初步定义: 
    可变类:当你获得这个类的一个实例引用时,你可以改变这个实例的内容。 
    不可变类:当你获得这个类的一个实例引用时,你不可以改变这个实例的内容。不可变类的实例一但创建,其内在成员变量的值就不能被修改。 
    举个例子:String和StringBuilder,String是immutable的,每次对于String对象的修改都将产生一个新的String对象,而原来的对象保持不变,而StringBuilder是mutable,因为每次对于它的对象的修改都作用于该对象本身,并没有产生新的对象。

    String对象是不可变的。也就是说可以给一个String对象加任意多的别名。因为String对象具有只读特性,所以指向它的任何引用都不可能改变它的值。

     1 public class Immutable {
     2     public static String upcase(String s) {
     3         return s.toUpperCase();
     4     }
     5     public static void main(String[] args) {
     6         String q = "howdy";
     7         print(q);
     8         String qq = upcase(q);
     9         print(qq);
    10         print(q);
    11     }
    12 }
    13 //结果:howdy HOWDY howdy
    View Code

    上述代码的解释:当把q传给upcase()方法时,实际传递的是引用的一个拷贝,这个引用所指的对象一直待在某个物理位置上。而对于upcase()的定义,传入其中的引用有了名字s,只有upcase()运行的时候,局部引用s才存在,一旦upcase()运行结束,s就消失了。而upcase()的返回值,其实只是最终结果的引用。而原本的q还在原地。

    因为String的不可变性,所对string字符串做的所有的变更字符串的操作,都会导致new的产生,这样也就改变了upcase传进去的string的地址,所以原q是没有任何变化的。

    通过反射改变String对象:

     1     //创建字符串"Hello World", 并赋给引用s
     2     String s = "Hello World"; 
     3     System.out.println("s = " + s); //Hello World
     4 
     5     //获取String类中的value字段
     6     Field valueFieldOfString = String.class.getDeclaredField("value");
     7     //改变value属性的访问权限
     8     valueFieldOfString.setAccessible(true);
     9 
    10     //获取s对象上的value属性的值
    11     char[] value = (char[]) valueFieldOfString.get(s);
    12     //改变value所引用的数组中的第5个字符
    13     value[5] = '_';
    14     System.out.println("s = " + s);  //Hello_World
    View Code

    3.重载的“+”操作符

    不可变行带来一定的效率问题。而Java仅对"+"和"+="两个操作符重载过,且Java不允许程序员重载任何操作符。

    1 public class Main {
    2     public static void main(String[] args) {
    3         String mango = "mango";
    4         String s = "abc" + mango + "def" + 47;
    5         print(s);
    6     }
    7 }
    8 //结果:abcmangodef47
    View Code

    在s = "abc" + mango + "def" + 47;的语法中,编译器自动创建了一个StringBuilder对象,用以构造最终的String,并为每个字符串调用一次StringBuilder的append()方法,总计4次。最后调用toString()生成结果,并存为s。

     1 public class Test {
     2     public String implicit(String[] fields) {
     3         String result = "";
     4         for(int i = 0; i < fields.length; i++) {
     5             result += fields[i];
     6         }
     7         return result;
     8     }
     9     public String explicit(String[] fields) {
    10         StringBuilder result = new StringBuilder();
    11         for(int i = 0; i < fields.length; i++) {
    12             result.append(fields[i]);
    13         }
    14         return result.toString();
    15     }
    16 }
    View Code

    implicit()方法:每循环一次,会创建一个新的StringBuilder对象,而每循环一次,之前创建的StringBuilder对象就会被gc回收。

    explicit()方法:只生成一个StringBuilder对象。

    4.new String("abc")创建几个对象

    如果常量池中原来有“abc”,则只创建一个对象;否则创建两个对象。

    总结:需要经常改变内容的字符串最好不要用String,因为每次生成对象都会对系统新能产生影响,特别当内存中无引用对象多了以后,GC就会开始工作,会拖慢速度。

    适用于:少量的字符串操作的情况。

    二、StringBuilder:是非线程安全的

     适用于:单线程下在对字符串进行大量操作的情况

    三、StringBuffer:是线程安全的

    适用于:多线程下对字符串进行大量操作的情况。

    三者运行效率的一般情况:StringBuilder>StringBuffer>String

    特殊情况:

    String str="abc"+"de";//更快
    StringBuilder stringBuilder=new StringBuilder().append("abc").append("de");

    这里的str会比stringBuilder快,因为str的赋值操作相当于str = "abcde",之所以会这样是因为有字符串常量池的存在。

    而如果写成下面的形式,string依旧很慢:

    String str1="abc";
    String str=str1+"de";

    因为会导致新对象的产生。

    从存取上来说,String>StringBuffer

    从多次改编上来说,StringBuffer>String

  • 相关阅读:
    Linux下解压分包文件zip(zip/z01/z02)
    Ubuntu 16.04安装Notepadqq编辑器替代Notepad++
    Ubuntu 16.04安装NASM汇编IDE-SASM
    java命令--jstack 工具
    详述 hosts 文件的作用及修改 hosts 文件的方法
    译:Java 中的正则表达式性能概述
    译:25个面试中最常问的问题和答案
    Android中使用GoogleMap的地理位置服务
    Android 从imageview中获得bitmap的方法
    Android通过百度地图API用Service和Alarm在后台定时获取地理位置信息
  • 原文地址:https://www.cnblogs.com/cing/p/7756064.html
Copyright © 2011-2022 走看看