String 类

    字符串是一个特殊的对象,一旦初始化就不可以被改变


1)比较下面的表达式的区别

  1. String str1 = "abc";

  2. String str2 = new String( "abc" );

    第一种先在栈中创建一个对String类的对象引用变量str1,然后去查找 "abc" 是否被保存在字符串常量池中。

    如果没有则在栈中创建三个char型的值 'a'、'b'、'c',然后在堆中创建一个String对象object,它的值是刚才在栈中创建的三个char型值组成的数组{ 'a' , 'b' , 'c'},接着这个String对象object被存放进字符串常量池,最后将str1指向这个对象的地址。

    如果 "abc" 已经被保存在字符串常量池中,则在字符串常量池中找到值为 "abc" 的对象object,然后将str1指向这个对象的地址。

第一种特点:JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。

    第二种可以分解成两步1、String object =  "abc" ; 2、String str2 = new String(object); 第一步参考第一种创建方式,而第二步由于 "abc" 已经被创建并保存到字符串常量池中,因此jvm只会在堆中新创建一个String对象,它的值共享栈中已有的三个char型值。
第二种特点:一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象。



2)==和equals的区别:
    因为java所有类都继承于Object基类,而Object中equals用==来实现,所以equals和==是一样的,都是比较对象地址,java api里的类大部分都重写了equals方法,包括基本数据类型的封装类、String类等。对于String类==用于比较两个String对象的地址,equals则用于比较两个String对象的内容(值)。



3)String 功能查找练习

	@Test
	public void  test0(){
        String str = "afcdeabc";
		//1,获取a字母出现的位置。
		System.out.println("indexOf('a')="+str.indexOf('a'));//0
		System.out.println("lastindexOf('a')="+str.lastIndexOf('a'));//5
		//2,获取角标3上的字符。
		System.out.println("charAt(3)="+str.charAt(3));
		//3,将字符串转成大写
		String s1 = str.toUpperCase();
		System.out.println("uppercase="+s1);//ABCDEABC
		
		//4,该字符串是否以Demo开头,是否以.java结束。
		boolean b1 = str.endsWith(".java");
		boolean b2 = str.startsWith("Demo");	
		
		//5,该字符串中是否包含cd字符串。
		System.out.println("contains(\"cd\")="+str.contains("cd"));	
		//6,截取2,5之间的字符串。
		System.out.println("substring(2,5)="+str.substring(2,5));
		//7,将字符串中的a替换成k。
		System.out.println("replace('a','k')="+str.replace('a', 'k'));
		//8,字符串比较大小。
		System.out.println("compareTo(\"aaa\")="+str.compareTo("aaa"));
	}

        

        运行结果

            indexOf('a')=0

            lastindexOf('a')=5

            charAt(3)=d

            uppercase=AFCDEABC

            contains("cd")=true

            substring(2,5)=cde

            replace('a','k')=kfcdekbc

            compareTo("aaa")=5



4)compareTo(String anotherString) 
    按字典顺序比较两个字符串。

    public int compareTo(String anotherString)

按字典顺序比较两个字符串。该比较基于字符串中各个字符的 Unicode 值。按字典顺序将此 String 对象表示的字符序列与参数字符串所表示的字符序列进行比较。如果按字典顺序此 String 对象位于参数字符串之前,则比较结果为一个负整数。如果按字典顺序此 String 对象位于参数字符串之后,则比较结果为一个正整数。如果这两个字符串相等,则结果为 0;



5)String 编程练习1

indexOf(String str, int fromIndex) 
  返回指定子字符串在此字符串中第一次出现处的索引位置,从指定的fromIndex索引开始。


	/**
	 *  1,获取一个字符串中指定子串出现的次数。 "nbaernbatynbauklnba"
	 */
	@Test
	public void test1(){
		String str =  "nbaernbatynbauklnba";
		String sub = "nba";
		int count = 0;//计数
		int index = 0;//定义变量记录每次查找的真 实位置。
		while((index=str.indexOf(sub, index))!=-1){
			count++;
			index+=sub.length();
		}
		System.out.println("count="+count);
	}



6)String 编程练习2

trim() 
    返回字符串的副本,忽略前导空白和尾部空白。

	/**
	 * 自己写一个方法去除字符串两端的空白。 "   ab c    " --> "ab c",
	 * 实现和trim()同样的效果
	 */
	@Test
	public void test2(){
		String str =  "   ab c    ";
		System.out.println(myTrim(str));
	}
	
	public String myTrim(String str){
		if(!str.startsWith(" ")&& !str.endsWith(" ")){
			return str;
		}else{
			int start=0;
			int end = str.length()-1;
			
		//对头角标的位置进行空格的判断,如果是继续循环判断下一个是否是空格
			while(start<=end && str.charAt(start)==' '){
				start++;
			}
		// 对尾角标的位置进行空格的判断,如果是继续循环判断下一个是否是空格
			while(start<=end && str.charAt(end)==' '){
				end--;
			}
			return str.substring(start,end+1);//含头不含尾
		}
	}


7)String 编程练习3

	/**
	 * 将一个字符串反转。"acqzk" --> "kzqca";
	 */
	@Test
	public void test3(){
		String str = "acqzk";	
		System.out.println(reverse1(str));
		System.out.println(reverse2(str));
	}
	//利用StringBuffer
	public String reverse1(String str) {
		StringBuffer sb = new StringBuffer();
		for(int i=str.length()-1;i>-1;i--){
			sb.append(str.charAt(i));
		}
		return sb.toString();	
	}
	//利用数字
	private String reverse2(String str) {
		char[] ch = str.toCharArray();
		for(int start=0,end=ch.length-1;start<end;start++,end--){
			char temp = ch[start]; 
			ch[start] = ch[end];
			ch[end] = temp;
		}
		return new String(ch);
	}


8)String 编程练习4

	/**
	 *获取两个字符串最大相同子串。"xcvcctvbsdf"  "tyuicctvonmyui"
	 */
	@Test
	public void test4(){
		String str1 = "xcvcctvssbsdf";
		String str2 = "tyuicctvssonmyui";
		String s1 = getMaxSub(str1,str2);
		System.out.println(s1);
		String s2 = getMaxSubString(str1,str2);
		System.out.println(s2);
	}

	private String getMaxSub(String str1, String str2) {
		if(str1.length()>str2.length()){
			String temp =str1;
			str1=str2;
			str2=temp;
		}
		
		int end = str1.length();
		for(int i=0;i<=end;i++){
			for(int j=0;j<=i;j++){
				if(i<end-j){
					String s = str1.substring(i-j,end-j);
					System.out.println("s = "+s);
					if(str2.contains(s)){
						return s;
					}					
				}
			}
		}
		return null;	
	}
	
	public String getMaxSubString(String s1, String s2) {
		//1,通过图例分析,大圈套小圈。
		for (int i = 0; i < s2.length(); i++) {
			for(int x = 0,y = s2.length() - i; y != s2.length()+1; x++,y++){
				//2,根据x,y角标获取s2的长度依次递减的子串。
				String temp = s2.substring(x,y);
				System.out.println(temp);
				if(s1.contains(temp)){
					return temp;
				}
			}
			
		}
		return null;
	}