黑马程序员-Java中只读类String和StringBuffer、StringBuilder类)

                                -----------android培训、java培训、java学习型技术博客、期待与您交流!------------

                                              Java中只读类String和StringBuffer、StringBuilder类

一、String类
   1、String类被final修饰符修饰,所以不能被继承;
   2、字符串一旦被初始化就不可以被改变;
   3、利用public String(char[] value)初始化String对象
      这种半初始化也可以建立String对象
             char[] ch = new char[5];
             ch[3] = 'a';
             ch[4] = 'b';
             String s = new String(ch);
             System.out.println(s);
   4、在Java中,初始化String分为两种:
 String s1 = "abc";
 String s2 = new String("abc")
      区别:方法1中,先在栈内存中查找有没有"abc"这个字符串对象存在,如果存在就把s1指向这个字符串对象;
            如果不存在,编译时就在方法区中的静态常量池中建立一个"abc"对象,然后把就把s1指向这个字符串对象;
            方法2中,执行方法1的过程,然后不论栈内存中是否已经存在"abc"这个字符串对象,
     都会在堆中新建一个new String()对象,把"abc"这个对象的成员属性char[] value的栈内存地址赋给
     new String()对象的成员属性char[] value。
   5、equals()方法
           public boolean equals(Object anObject)
        将此字符串与指定的对象比较。当且仅当该参数不为 null ,并且是与此对象表示相同字符序列的
      String 对象时,结果才为 true。
           System.out.println(s1.equals(s2));    //true   str5的值str6的值比对
   6、本地intern()方法返回栈中值的内存地址
           public native String intern();
    String s3 = s2.intern();
      当调用 intern 方法时,就是返回s1中栈的地址值。

   

class StringDemo{
	public static void main(String[] args) 
	{
		String s1 = "abc";
		String s2 = new String("abc");

		System.out.println(s1==s2);
		System.out.println(s1.equals(s2));

		String s3 = s2.intern();
		System.out.println(s1==s3);
	}
}
结果:false
      true
	  true


  

   7、操作字符串的方法
      (1)获取
           a、字符串中包含的字符数,也就是字符串的长度;
        int length();
    b、根据位置获取位置上的某个字符;
        char charAt(int index);
    c、根据字符获取该字符在字符串中的位置;
        int  indexOf(int ch);返回ch在字符串中第一次出现的位置
        int  indexOf(int ch,int fromindex);//从fromindex指定的位置开始,获取ch在字符串中的出现的位置
        int  indexOf(String str);//从fromindex指定的位置开始,获取字符串str在字符串中的出现的位置
        int  indexOf(String str,int fromindex);//从fromindex指定的位置开始,获取str在字符串中的出现的位置
               int  lastIndexOf(int ch); //反向索引
      (2)判断
           a、字符串中是否包含某一个子串;
  public boolean contains(CharSequence s);
      
    注意:indexOf(String str)可以索引str第一次出现的位置,如果返回-1,表示str不在字符串中村子;
          所以也可以用于对存储判读是否包含,例如 if(str.indexOf("aa")!=-1). 该方法既可以判断,也可以
   获取出现的位置。
    b、字符串是否不为空
       public boolean isEmpty();
    c、字符串是否以指定内容开头
  public boolean startsWith(String prefix);
    d、字符串是否以指定内容结束
  public boolean endsWith(String suffix);
    e、判断字符串内容是否相同,覆盖了Object类中的equals方法
          public boolean equals(Object anObject);
           f、判断字符串内容是否相同,但忽略大小写
          public boolean equalsIgnoreCase(String anotherString);
       (3)转换
    a、将字符数组转成字符串。
       构造函数:String(char[]);
   String(char[],offset,count);//将字符数组中的一部分转成字符串
       静态方法:
   public static String copyValueOf(char[] data);
   public static String copyValueOf(char[] data,int offset,int count);
   public static String valueOf(char[] data);
     b、将字符串转成字符数组。**
  public char[] toCharArray();


     c、将字节数组转成字符串。
   String(byte[]);
   String(byte[],offset,count);//将字节数组中的一部分转成字符串
     d、将字符串转成字节数组。
   public byte[] getBytes();


     e、将基本数据类型转成字符串。
   public static String valueOf(int i);
   public static String valueOf(double d);
        例如:3+"";转换为字符串也可以 String.valueOf(3);
        特殊:字符串和字节数组在转换过程中,是可以指定编码表的。

        (4)替换
  public String replace(char oldChar,char newChar);

        (5)切割
  public String[] split(String regex);

        (6)子串:获取字符串中的一部分。
  public String substring(int beginIndex);
  public String substring(int beginIndex,int endIndex);

        (7)转换/去除空格/比较
      a、将字符串转成大写或则小写。
   public String toUpperCase();
   public String toLowerCase();

      b、将字符串两端的多个空格去除。
  public String trim();

      c、对两个字符串进行自然顺序的比较。
  public int compareTo(String anotherString);
   

 

class  StringMethodDemo
{
	public static void method_case(){
		String s = "    Hello Java     ";
		sop(s.toLowerCase());
		sop(s.toUpperCase());

		sop(s.trim());

		String s1 = "a1c";
		String s2 = "aaa";
		sop(s1.compareTo(s2));
	}

	public static void method_sub(){
		String s = "abcdef";

		sop(s.substring(2));//从指定位置开始到结尾。如果角标不存在,会出现字符串角标越界异常。
		sop(s.substring(2,4));//包含头,不包含尾。s.substring(0,s.length());
	}

	public static void  method_split(){
		String s = "zhagnsa,lisi,wangwu";
		String[] arr  = s.split(",");
		for(int x = 0; x<arr.length; x++)
		{
			sop(arr[x]);
		}
	}

	public static void method_replace(){
		String s = "hello java";

		//String s1 = s.replace('q','n');//如果要替换的字符不存在,返回的还是原串。

		String s1 = s.replace("java","world");
		sop("s="+s);
		sop("s1="+s1);
	}

	public static void method_trans(){
		//字符数组转换为字符串
		char[] arr = {'a','b','c','d','e','f'};
		String s= new String(arr,1,3);
		sop("s="+s);

        //字符串转换为字符数组
		String s1 = "zxcvbnm";
		char[] chs = s1.toCharArray();
		for(int x=0; x<chs.length; x++)
		{
			sop("ch="+chs[x]);
		}
	}

	public static void method_is(){
		String str = "ArrayDemo.java";
		
		//判断文件名称是否是Array单词开头。
		sop(str.startsWith("Array"));

		//判断文件名称是否是.java的文件。
		sop(str.endsWith(".java"));

		//判断文件中是否包含Demo
		sop(str.contains("Demo"));

		//判断文件中是否包含.java,会有问题,如array.java.txt
		sop(str.contains(".java"));
	}

	public static void method_get(){
		String str = "abcdeakpf";

		//长度
		sop(str.length());

		//根据索引获取字符。
		sop(str.charAt(4));//当访问到字符串中不存在的角标时会发生StringIndexOutOfBoundsException。

		//根据字符获取索引
		sop(str.indexOf('m',3));//如果没有找到,返回-1.
		
		//反向索引一个字符出现位置。
		sop(str.lastIndexOf("a"));

		
	}
	public static void main(String[] args) 
	{
		//method_case();
		//method_trans();
		method_is();
		//method_get();
	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}


二、关于String的不可变设计:
        String是不可改变类(记:基本类型的包装类都是不可改变的)的典型代表,也是Immutable设计模式的典型应用,
    String变量一旦初始化后就不能更改,禁止改变对象的状态,从而增加共享对象的坚固性、减少对象访问的错误,
    同时还避免了在多线程共享时进行同步的需要。
   
    Immutable模式的实现主要有以下两个要点:
    1.除了构造函数之外,不应该有其它任何函数(至少是任何public函数)修改任何成员变量。
    2.任何使成员变量获得新值的函数都应该将新的值保存在新的对象中,而保持原来的对象不被修改。
 
    String的不可变性导致字符串变量使用+号的代价:
    例9:
 String s = “a” + "b” + "c”;
 String s1  =  "a";
 String s2  =  "b";
 String s3  =  "c";
 String s4  =   s1  +  s2  +  s3;  
        分析:变量s的创建等价于 String s = “abc”; 由上面例子可知编译器进行了优化,这里只创建了一个对象。
    由上面的例子也可以知道s4不能在编译期进行优化,其对象创建相当于:
 StringBuffer temp = new StringBuffer();
 temp.append(s1).append(s2).append(s3);
 String s = temp.toString();
    由上面的分析结果,可就不难推断出String 采用连接运算符(+)效率低下原因分析,形如这样的代码:
 
 public class Test {
     public static void main(String args[]) {
  String s = null;
      for(int i = 0; i < 100; i++) {
   s += "a";
      }
     }
 }

      每做一次 + 就产生个StringBuffer对象,然后append后就扔掉。下次循环再到达时重新产生个StringBuffer对象,
    然后append 字符串,如此循环直至结束。如果我们直接采用StringBuffer对象进行append的话,我们可以节省N - 1次
    创建和销毁对象的时间。所以对于在循环中要进行字符串连接的应用,一般都是用StringBuffer或StringBulider对象来
    进行append操作。


三、StringBuffer类
    String不可变类的同志类,或者叫字符的容器类,是字符串缓冲区。

    1、特点:
       (1)长度是可变化的。
       (2)可以字节操作多个数据类型。
       (3)最终会通过toString方法变成字符串。

    2、操作字符串的方法( C create U update R read D delete)
       (1)存储
  public StringBuffer append():将指定数据作为参数添加到已有数据结尾处。
  public StringBuffer insert(index,数据):可以将数据插入到指定index位置。
       (2)删除
  public StringBuffer delete(start,end):删除缓冲区中的数据,包含start,不包含end。
  public StringBuffer deleteCharAt(index):删除指定位置的字符。
       (3)获取
  public char charAt(int index); //获取指定位置的字符
  public int indexOf(String str); //获取str的位置
  public int lastIndexOf(String str);//获取str的最后的位置
  public int length();//获取长度
  public String substring(int start, int end); //获取从strat到end-1位置的字符串
       (4)修改
  public StringBuffer replace(start,end,str); //用字符串str替代从start到end-1的字符串
  public void setCharAt(int index, char ch) ;//用ch字符替代index位置上的字符
       (5)反转
  public StringBuffer reverse();
 
       (6)将缓冲区中指定数据存储到指定字符数组中。
  public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin);
      

四、StringBuilder类
    1、特点
        JDK1.5 版本之后出现了StringBuilder.一个可变的字符序列。

    2、比较
       StringBuffer是线程同步: 此类提供一个与 StringBuffer 兼容的 API,但不保证同步。
    该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。
    StringBuilder是线程不同步。

    3、如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。

    4、它的方法是和StringBuffer类一样的,不过要注意
       (1)因为没有线程锁,所以StringBuilder类的对象可以被多个线程同时操作;
       (2)如果要在多线程中使用StringBuffer类对象,只要手动加锁就可以了。
 

class StringBufferDemo {
	public static void sop(String str){
		System.out.println(str);
	}

	public static void method_saveCharBuffer(){
		StringBuffer sb = new StringBuffer("abcdef");
		char[] chs = new char[6];
		sb.getChars(1,4,chs,1);

		for(int x=0; x<chs.length; x++)
		{
			sop("chs["+x+"]="+chs[x]+";");
		}
	}

	public static void method_update(){
		StringBuffer sb  = new StringBuffer("abcde");

        //sb.replace(1,4,"java");
		sb.setCharAt(2,'k');

		sop(sb.toString());
	
	}

	public static void method_del(){
		StringBuffer sb  = new StringBuffer("abcde");
		
        sb.delete(1,3);

		//清空缓冲区。
		//sb.delete(0,sb.length());

		//sb.delete(2,3);
		//sb.deleteCharAt(2);

		sop(sb.toString());
	}

	public static void method_add(){
		StringBuffer sb = new StringBuffer();

		sb.append("abc").append(true).append(34);
        //StringBuffer sb1 = sb.append(34);
        //sop("sb==sb1:"+(sb==sb1));

		sb.insert(1,"qq");
		sop(sb.toString());//abctrue34
		//sop(sb1.toString());
	}

	public static void main(String[] args) {
		//method_add();
		//method_del();
		//method_update();
		//method_saveCharBuffer();

		//StringBuilder类测试
		StringBuilder sb = new StringBuilder("abcdef");
		char[] chs = new char[6];
		sb.getChars(1,4,chs,1);

		for(int x=0; x<chs.length; x++)
		{
			sop("chs["+x+"]="+chs[x]+";");
		}
	}
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值