zoukankan      html  css  js  c++  java
  • Java基础String类

    String是一个对象

    String不属于8种基本数据类型(byte, char, short, int, float, long, double, boolean),String是对象,所以其默认值是null。

    String是一种特殊的对象,有其它对象没有的一些特性,通过JDK发现:

    public final class String
        implements java.io.Serializable, Comparable<String>, CharSequence {
        /** The value is used for character storage. */
        private final char value[];
    
        /** Cache the hash code for the string */
        private int hash; // Default to 0
         public String() {
            this.value = new char[0];
        }
         public String(char value[]) {
            this.value = Arrays.copyOf(value, value.length);
        }
    | 
    • String类是final的,不可被继承
    • String类是的本质是字符数组char[], 并且其值不可改变,每一个构造的String对象,都是作为常量存储在内存中
    • String类对象有个特殊的创建的方式,就是直接指定比如String x = "abc","abc"就表示一个字符串对象;而x是"abc"对象的地址,也叫做"abc"对象的引用。
    • String对象可以通过 “+” 串联,串联后会生成新的字符串。

    String对象的创建

    归纳起来有三类

    1. 使用new关键字创建字符串,比如String s1 = new String("abc");
    2. 直接指定。比如String s2 = "abc";
    3. 使用串联生成新的字符串。比如String s3 = "ab" + "c";

    创建原理

        public static void main(String[] args){  
            String s0 = "adanac";  
            String s1 = "adanac";  
            String s2 = "ada" + "nac";  
              
            System.out.println(s0 == s1);       // true  
            System.out.println(s0 == s2);       // true  
        }
    

    例子中的s0和s1中的”adanac”都是字符串常量,它们在编译期就被确定了,所以s0==s1为true;

    当使用String s1 = "adanac"; 方式时,JVM会拿着"adanac"在String池中找是否存在内容相同的字符串对象,如果不存在,则在池中创建一个字符串s,否则,不在池中添加。

    而”ada”和”nac”也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中”adanac”的一个引用。

    所以我们得出s0==s1==s2!

        public static void main(String[] args){  
            String s0 = "adanac";  
            String s1 = new String("adanac");  
            String s2 = "ada" + new String("nac");  
              
            System.out.println(s0 == s1);       // false  
            System.out.println(s0 == s2);       // false  
            System.out.println(s1 == s2);       // false  
        }
    

    用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。

    此例中s0还是常量池中"adanac"的应用,s1因为无法在编译期确定,所以是运行时创建新对象”adanac”的引用,s2因为有后半部分new String("nac")所以也无法在编译期确定.

    常量池(constant pool)

    指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。

    关于 equals() 和 ==
    equals对于String简单来说就是比较两字符串的Unicode序列是否相当,如果相等返回true;而==是比较两字符串的地址是否相同,也就是是否是同一个字符串的引用。

    常见的操作方法

    获取

    public class Test {
        public static void main(String srgs[])
        { 
    
            String str = "hello java!" ; 
      
            String str1 = new String("hello java!") ;
    
    		//str 和 str1 的区别在于:str 内存中有一个对象,而str1 内存中有两个对象。
             
            sop(str.length()) ;
            
            sop(str.charAt(i))  ; 
            sop(str.indexOf('a')) ;
            sop(str.indexOf('a',7)) ;
    
            sop(str.indexOf("java")) ;
            sop(str.lastIndexOf('a')) ; 
        }
        //打印函数:
        public static void sop(Object obj) 
        {
            System.out.println(obj); 
        }
    }
    
    1. 字符串中包含的字符数,即字符串的长度; int length() ;注意:String 类的 length()  是一个方法; 而 char 类型数组调用的length , 是属性。
    2. 根据位置获取位置上某个字符。 char charAt(int index) ; index 是下标。
    3. 根据字符获取该字符在字符串中的位置:
      • int indexOf(int ch) ; 返回的是 ch 在字符串中第一次出现的位置。其中 ch 是字符的ASCII 码。 
      • int indexOf(int ch , int fromIndex) ; 从fromIndex 指定位置开始,在字符串中第一次出现的位置.
      • int indexOf(String st) ; 返回的是 st 在字符串中第一次出现的位置。
      • int lastIndexOf(int ch) ; 返回指定字符在此字符串中最后一次出现处的索引。

    判断

    public class Test{
        public static void main(String args[])
        {
            String str1 = "hello java!" ; 
            String str2 = new String("hello java!") ;  
            
            System.out.println(str1.equals(str2));  //true [String类重写了Object类的equals 方法]
            System.out.println(str1 == str2);  //false
        } 
    }
    

      判断常用的方法有:

        1、判断字符串中是否包含某一个字串。

          boolean contains(CharSequence cs) ; 

        2、字符串中是否为空:

          boolean isEmpty() ; 其原理就是判断字符长度是否为0。

        3、判断字符串是否以指定类容开头:

          boolean startsWith(String str) ; 

        4、判断字符串是否以指定类容结尾:

          boolean endsWith(String cs) ;

        5、判断字符串内容是否相等:

          boolean equals(Obeject obj) ;    

        6、 判断内容是否相同,并忽略大小写。

          boolean equalsIgnoreCase(String str)

    转换

    public class Test {
        public static void main(String args[])
        {
            char[] ch = {'h','e' ,'l' ,'l' ,'o' ,' ' , 'j' , 'a' , 'v' ,'a'} ;
    	// 构造函数转换:
    	// 将字符数组转换成字符串:
            String str1 = new String (ch) ; 
            System.out.println(str1);
    		// 从ch[] 下标 6开始,后的4个字符 ,转换成字符串。
            String str2 = new String (ch,6,4) ;
            System.out.println(str2);
            
    	//  静态方法:
    	//  将字符数组转换成字符串:
            String str3 = String.copyValueOf(ch) ; 
            System.out.println(str3); 
    	//  从ch[] 下标 6开始,后的4个字符 ,转换成字符串。
            String str4 = String.copyValueOf(ch,0,5) ;
            System.out.println(str4);
            
            String str = "hello java" ; 
    	// 将字符串转换成字符数组;
            char[] ch1 = str.toCharArray() ;
            for(int i = 0 ; i < ch1.length ; i ++)
                System.out.print("'"+ch1[i] +"'");
            System.out.println();   
        }
    }
    

    1、将字符数组转换成字符串:

       构造方法:String(char[] ch)

            String(char[] ch , int offset , int count ) ; 将字符数组中的一部分转成字符串。

            其中:offset 参数是子数组第一个字符的索引;count 参数指定子数组的长度。如果从offset 后面的字符数小于count 则会异常。

            注意:该子数组的内容已被复制;后续对字符数组的修改不会影响新创建的字符串。

    2、将字符串转换成字符数组。

      char[] toCharArray() ; 

    3、将字节数转成字符串。

      构造方法:String(byte[] by) ;

           String(byte[] by , int offset , int count) ;

    4、将字符串转成字节数组。

      byte[] getByte() ;

    5、将基本数据类型转换成字符串。

      static String valueOf(基本数据类型)

    替换、切割、去除空格和比较

    • String replace(char oldChar , char newChar) : 返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。
    • String[] split(String regex) : 根据给定正则表达式的匹配拆分此字符串。
    • String trim():将字符串两端的多个空格去除
    • int compareTo(String str):对两个字符串进行自然顺序的比较。 ; 当另一个字符串大于该字符串时,返回负数;相等,则返回0;否则返回正数。
    String str = "    hello,java,Adanac    " ; 
          
    //替换字符
    String str1 = str.replace(',', ' ') ;
           
    //切割
    String[] str2 = str.split(",") ; 
    
    // 除去字符串两端的多个空格:
    System.out.println(str1.trim()); 
    
    String str2 = "hello world " ; 
    //对比两个字符串进行自然顺序的比较
    System.out.println(str.compareTo(str2));
    

     练习
    1,模拟一个trim方法,去除字符串两端的空格。
    2,将一个字符串进行反转。将字符串中指定部分进行反转,"abcdefg";abfedcg

    class StringTest 
    {
    
    	public static void sop(String str)
    	{
    		System.out.println(str);
    	}
    	public static void main(String[] args) 
    	{
    		String s = "      ab cd      ";
    
    		sop("("+s+")");
    		s = myTrim(s);
    		sop("("+s+")");
    
    		sop("("+reverseString(s)+")");
    		
    	}
    
    
    	//练习二:将字符串反转。
    	/*
    	思路:
    	1,将字符串变成数组。
    	2,对数组反转。
    	3,将数组变成字符串。
    	*/
    
    	public static String reverseString(String s,int start,int end)
    	{
    		//字符串变数组。
    		char[] chs = s.toCharArray();
    
    		//反转数组。
    		reverse(chs,start,end);
    
    		//将数组变成字符串。
    		return new String(chs);
    	}
    	public static String reverseString(String s)
    	{
    		return reverseString(s,0,s.length());
    		
    	}
    
    	private static void reverse(char[] arr,int x,int y)
    	{
    		for(int start=x,end=y-1; start<end ; start++,end--)
    		{
    			swap(arr,start,end);
    		}
    	}
    	private static void swap(char[] arr,int x,int y)
    	{
    		char temp = arr[x];
    		arr[x] = arr[y];
    		arr[y] = temp;
    	}
    
    	//练习一,去除字符串两端空格。
            /*思路:
    	1,判断字符串第一个位置是否是空格,如果是继续向下判断,直到不是空格为止。
    		结尾处判断空格也是如此。
    	2,当开始和结尾都判断到不是空格时,就是要获取的字符串。
            */
    	public static String myTrim(String str)
    	{
    		int start = 0,end = str.length()-1;
    
    		while(start<=end && str.charAt(start)==' ')
    			start++;
    
    		while(start<=end && str.charAt(end)==' ')
    			end--;
    
    		return str.substring(start,end+1);
    	}
    }
    

    3,获取一个字符串在另一个字符串中出现的次数。

    4,获取两个字符串中最大相同子串。第一个动作:将短的那个串进行长度一次递减的子串打印。

    class  StringTest
    {
    
    	/*
    	练习三。
    	获取一个字符串在另一个字符串中出现的次数。
    		"abkkcdkkefkkskk"
    
    		思路:
    		1,定义个计数器。
    		2,获取kk第一次出现的位置。
    		3,从第一次出现位置后剩余的字符串中继续获取kk出现的位置。
    			每获取一次就计数一次。
    		4,当获取不到时,计数完成。
    
    		*/
    		
    	public static int getSubCount(String str,String key)
    	{
    		int count = 0;
    		int index = 0;
    
    		while((index=str.indexOf(key))!=-1)
    		{
    			sop("str="+str);
    			str = str.substring(index+key.length());
    
    			count++;	
    		}
    		return count;
    	}
    
    	/*
    	练习三,方式二。
    
    	*/
    	public static int getSubCount_2(String str,String key)
    	{
    		int count = 0;
    		int index = 0;
    
    		while((index= str.indexOf(key,index))!=-1)
    		{
    			sop("index="+index);
    			index = index + key.length();
    					count++;
    		}
    		return count;
    	}
    
    	public static void main(String[] args) 
    	{
    		String str = "kkabkkcdkkefkks";
    			///sop("count====="+str.split("kk").length);不建议使用。
    		sop("count="+getSubCount_2(str,"kk"));
    	}
    
    	public static void sop(String str)
    	{
    		System.out.println(str);
    	}
    }
    
     
    
    class  StringTest
    {
    	/*
    	练习四。
    	获取两个字符串中最大相同子串。第一个动作:将短的那个串进行长度一次递减的子串打印。
    	"abcwerthelloyuiodef"
    	"cvhellobnm"
    	思路:
    		1,将短的那个子串按照长度递减的方式获取到。
    		2,将每获取到的子串去长串中判断是否包含,
    			如果包含,已经找到!。
    	*/
    	public static String getMaxSubString(String s1,String s2)
    	{
    
    		String max = "",min = "";
    
    		max = (s1.length()>s2.length())?s1: s2;
    
    		min = (max==s1)?s2: s1;
    		
    		sop("max="+max+"...min="+min);
    		for(int x=0; x<min.length(); x++)
    		{
    			for(int y=0,z=min.length()-x; z!=min.length()+1; y++,z++)
    			{
    				String temp = min.substring(y,z);
    				
    				sop(temp);
    				if(max.contains(temp))//if(s1.indexOf(temp)!=-1)
    					return temp;
    			}
    		}
    		return "";
    	}
    
    
    	public static void main(String[] args) 
    	{
    		String s1 = "ab";
    		String s2 = "cvhellobnm";
    		sop(getMaxSubString(s2,s1));
    	}
    
    	public static void sop(String str)
    	{
    		System.out.println(str);
    	}
    }
    

    StringBuffer类

    StringBuffer 对象则代表一个字符序列可变的字符串。当一个 StringBuffer 被创建以后,通过StringBuffer 提供的一系列方法可以改变这个字符串对象的字符序列,一旦通过StringBuffer 生成了最终想要的字符串,就可以调用它的toString 方法将其转换成一个String 对象。

    StringBuffer类被final修饰,不能被继承

    StringBuffer和数组都是容器,StringBuffer作为容器类的特点:

    • 长度是可变的
    • 可以操作多个数据类型
    • 使用toString()转换成字符串

    StringBuffer类常用方法

    添加:

    • StringBuffer append(数据) : 将指定的数据作为参数添加到已有的数据结尾处。返回的还是原缓冲区对象。
    • StringBuffer insert(int index , 数据) : 可以将数据插入到指定角标index 位置。注意:index不能越界。

    删除:

    • StringBuffer delete(int start , int end) ;删除缓冲区的数据,包含start,不包含end。
    • StringBuffer deleteCharAt(int index) ; 删除指定位置的字符。

    获取:

    • char charAt(int index) ; 获取指定位置的字符。
    • void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) 将字符从此序列复制到目标字符数组 dst。
    • int indexOf(String str) ; 获取子串第一次出现的位置。
    • int lastIndexOf(String str) 返回最右边出现的指定子字符串在此字符串中的索引。
    • int lastIndexOf(String str, int fromIndex) 返回最后一次出现的指定子字符串在此字符串中的索引。
    • int length() 返回长度(字符数)。
    • String toString() 返回此序列中数据的字符串表示形式。
    • String substring(int start) 返回一个新的 String,它包含此字符序列当前所包含的字符子序列。
    • String substring(int start, int end) 返回一个新的 String,它包含此序列当前所包含的字符子序列。

         注意:获取方法和String 类中的方法类似。

    修改 :

    • StringBuffer replace(int start , int end , String str):使用给定String 中字符代替此序列中的子串中的字符。
    • void setChatAt(int index , char ch) :将给定索引出的字符设置成ch . 
    • StringBuffer reverse() :将此字符序列用其反转形式取代。
    • void setCharAt(int index, char ch) : 将给定索引处的字符设置为 ch。
    • void setLength(int newLength) : 设置字符序列的长度。
    public class StringBufferDemo 
    {
        public static void main(String[] args)
        {  
            System.out.println("");
            DeleteString(new StringBuffer("hello java")) ;
            System.out.println("-------------------------------");
            ReplaceString(new StringBuffer("hello java")) ;
        }
        public static void CreateString(StringBuffer stringBuffer )
        {
    	// 添加数据到stringBuffer 结尾处,
            stringBuffer.append("hello").append("java").append(520).append(true) ; 
            System.out.println(stringBuffer);
    		
    	//在指定位置添加数据。
            stringBuffer.insert(0, "heima,"); 
            System.out.println(stringBuffer);
        }
        public static void DeleteString(StringBuffer stringBuffer)
        { 
    	//删除start至end的字符序列。
            stringBuffer.delete(0,6);
            System.out.println(stringBuffer);
    
    	//删除指定位置的字符
            stringBuffer.deleteCharAt(1) ;
            System.out.println(stringBuffer); 
        }
        public static void ReplaceString(StringBuffer stringBuffer)
        {
    	//替换指定字符序列。
            stringBuffer.replace(6, stringBuffer.length(), "adanac") ; 
            System.out.println(stringBuffer);
            stringBuffer.setCharAt(5, ',') ;
            System.out.println(stringBuffer);
    
    	//反转
            stringBuffer.reverse(); 
            System.out.println(stringBuffer); 
        }
    }
    

     StringBuilder类

    • 一个可变的字符序列
    • 该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。

    StringBuilder 类和 StringBuffer 类基本相似:都是可变的字符序列

    在不用考虑线程安全的情况下使用 StringBuilder 类。

    StringBuider 类和 StringBuffer 类二者之间的区别

    • StringBuilder类是线程不同步的,没有实现线程安全功能,所以性能略高,它比 StringBuffer 要快
    • StringBuffer类是线程同步的,线程安全的。
  • 相关阅读:
    QFramework 使用指南 2020(二):下载与版本介绍
    QFramework 使用指南 2020 (一): 概述
    Unity 游戏框架搭建 2018 (二) 单例的模板与最佳实践
    Unity 游戏框架搭建 2018 (一) 架构、框架与 QFramework 简介
    Unity 游戏框架搭建 2017 (二十三) 重构小工具 Platform
    Unity 游戏框架搭建 2017 (二十二) 简易引用计数器
    Unity 游戏框架搭建 2017 (二十一) 使用对象池时的一些细节
    你确定你会写 Dockerfile 吗?
    小白学 Python 爬虫(8):网页基础
    老司机大型车祸现场
  • 原文地址:https://www.cnblogs.com/iadanac/p/3826499.html
Copyright © 2011-2022 走看看