字符串 - java中的String

关于String的一些实用技能

一、String

面试经常会看到关于String,到底String是怎么一回事呢 ?

  • String的常量池
    JVM在堆中开辟了一段空间迎来缓存所有使用字面量
    创建的字符串对象,只要发现已经创建过的字符串
    字面量创建新字符串时,JVM会直接使用缓存的对象
    而不是在创建新对象,这样做避免内存堆积大量
    内容一样的字符串对象,降低内存开销
   一、
        //直接量 字面量
		String s1 = "123abc";
		String s2 = "123abc";//重用S1创建的对象
		String s3 = "123abc";//一样重用

		System.out.println(s1==s2);//true
		System.out.println(s1==s3);//true

上边为什么会是true?
s1、s2、s3 三个里面内容是相同的;s3会利用之前(s1)的缓存123abc 。( s2同理 )
所以为true。

   二、	        
        String s1 = "123abc";
		String s2 = "123abc";
		//一旦修改内容,就会创建新对象
		s1 = s1+"!";//s1不在指向原对象
		System.out.println("s1:"+s1);//123abc!
		System.out.println("s2:"+s2);//123abc

这个时候s1输出为 123abc!,会不在指向原对象。

   三、
		String s2 = "123abc";
		//new是一个比较强制的操作,一定创建新对象
		String s4 = new String("123abc");
		System.out.println("s4:"+s4);
		System.out.println(s2==s4);//false

这次会输出false,因为new是一个比较强制的操作,一定创建个对象。
虽然内容相同,但是两者对象不同,所以比较为false!

   四、
        /**
         * 这里触发了编译器一个特点
         * 编译器在编译代码时若出现一个表达式
         * 参与的值都是字面量时,那么该计算表达式的结果
         * 是确定的,此时编译器计算表达式的结果,将结果替换表达式
         * 这样一来JVM每次执行字节码文件就不用计算了
         * 下面的代码会被编译器编译后为:
         * String s5="123abc";
         */
	   String s5 = "123"+"abc";
	   String s2 = "123abc";
	   System.out.println("s5:"+s5);
	   System.out.println(s2==s5);//true

上边说到了,编译器的特点。虽然两者是相加的,但表达式参与值为字面量,直接把结果确定;
两者对象比较,值相同,所以为false

  五、
	   String s = "123";
	   String s6 = s+"abc";
	   System.out.println(s2==s6);//false

上边说到了,当使用了字面量时,会自动变为结果进行比较。
当使用了一个变量,不是字面量时。进行比较对象,为false!

二、String不适合频繁修改

     字符串是不变对象,若想改变内容一定会创建新对象
     这样的做法源自JVM对字符串的优化,但是这样的做法
     弊端修改字符串时性能低下(虽然这样的操作不频繁)
     频繁修改产生大量垃圾,内存开销大,运行效率差

结论:String不适合频繁修改

三、String、StringBuffer、StringBuilder区别

StringBuffer与StringBuilder相同点都是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,
实际上是在一个对象上操作的。String每次操作会创建一些新的对象,所以速度快些。

不同点是StringBuilder是线程非安全的,StringBuffer是线程安全的, 当我们在字符串缓冲区被多个线程使用时,
JVM不能保证StringBuilder的操作是安全的,虽然它的速度最快,但是可以保证StringBuffer是可以正确操作的。
当然大多数情况下我们是在单线程下进行的操作,所以大多数情况下建议使用StringBuilder而不用StringBuffer的,
就是速度的原因。

对于三者使用的总结:
1.如果要操作少量的数据使用 String。
2.单线程操作字符串缓冲区,操作大量数据使用 StringBuilder。     
3.多线程操作字符串缓冲区,操作大量数据使用 StringBuffer。

--------------------------------------------------------

String的使用

1、 char charAt(int index)

  • 下标 获取当前字符串中指定位置对应的字符

    String str="thinking in java";
    char c=str.charAt(9);
    System.out.println(c);//i
    

注意:第一个是从0开始数的。
这时会输出String str变量中的第九个下标对应的。

2、int indexOf(String str)

  • 检定给定的当前字符串中的位置

  • 若当前字符串不包含给定内容,则返回值为-1

       String str="thinking in java";
       //查找str中"in"所在的位置
       int index = str.indexOf("in");//2
       
       System.out.println(index);
       //从指定位置开始查找第一次出现"in"的位置
       index = str.indexOf("in",3);
       System.out.println(index);//5
       
       //查找最后一次出现"in"位置
       index = str.lastIndexOf("in");
       System.out.println(index);//9
    

3、int length()

  • 获取当前字符串长度(字符个数)

      String str = "我爱java!!";
      int length = str.length();
      System.out.println("len:"+length);//len:8
    

4、boolean startsEith(String str)

boolean endsWith(String str)

  • 判断一个字符串是否以字符开始或结尾的

     String str="thinking in java";
     
     boolean starts =str.startsWith("thi");
     System.out.println("start:"+starts);//true
     
     boolean ends =str.endsWith("ava");
     System.out.println("ends:"+ends);//true
    

5、String substring(int start,int end)

  • 截取指定范围内的字符串,两个参数分别表示下标

  • 从start处开始,end结束(不包含end处的字符)

  • java API中的参数有一个特点,通常用两个数字表示

  • 范围时都是“含头不含尾”的。

      String str="eee.hhhh.com";
      
      String sub=str.substring(4,8);
      System.out.println(sub);//hhhh
      
      //从指定位置开始截取到字符串末尾
      sub=str.substring(4);
      System.out.println(sub);//hhhh.com
    

6、String toUpperCase()

String toLowerCase()

  • 将当前英文字符部分转换为全大写或全小写

      String str="我爱java,LALALA";
     String upper =str.toUpperCase();
     System.out.println(upper);//我爱JAVA,LALALA
    
     String lower=str.toLowerCase();
     System.out.println(lower);//我爱java,lalala
    

7、String trim()

  • 去除字符串两边的空白字符

     String str="   				h e l l o		";
     System.out.println(str); //  				h e l l o		
    
    
     String trim=str.trim();                                             
     System.out.println(trim);//hello
    
     System.out.println(str.trim());//hello
    

这两个结果都是相同的,只是用法不一样。

8、static String valueOf(XXX xxx)

  • 字符串提供了一组静态的重载的valueOf方法,作用

  • 是将其他类型转换为字符串

     int a=123;
     String s1=String.valueOf(a);
     System.out.println(s1);//123
    
     double d=123.123;
     String s2=String.valueOf(d);
     System.out.println(s2);//123.123
    
     String s3=a+"";
     System.out.println(s3);//123
    

补充StringBuffer的使用

    String str="努力学习java";

	StringBuilder b=new StringBuilder(str);
	System.out.println(b);

	/**
	 * 增
	 * append():将给定内容拼接到字符串末尾
	 */
	b.append(",为了找个好工作!");
	
	//获取StringBuilder内部表示的字符串
	str = b.toString();
	System.out.println(str);

	/**
	 * 改
	 * 怒力学习java,为了找个好工作!
	 * 怒力学习java,就是为了改变世界!
	 */
	b.replace(9,17,"为了改变世界!");
	System.out.println(b);

	/**
	 * 删
	 */
	b.delete(0,9);
	System.out.println(b);

	/**
	 * 插:
	 */
	b.insert(0, "活着,就是");
	System.out.println(b);

StringBuilder修改字符串性能

    StringBuilder builder = new StringBuilder("a");
	for(int i=0;i<100000000;i++){
		builder.append("a");
	}
	System.out.println("执行完毕!");

这样是在同一个变量改变,所以效率比较高,
StringBuufer是安全的,StringBuilder是不安全的。

---------------------------------------------------

String和正则表达式配合使用

关于正则表达式

大小写不同,意思也就不同

\w    [a-zA-Z0-9_]  单词字符
\W    非单词字符
\d    [0-9]      任意一个数字
\D    非数字
\s    空白
\S    非空白

1、 String支持正则表达式的方法一:

  • boolean matches(String regex)
  • 使用给定的正则表达式验证当前字符串是否符合格式

简单判断是否符合邮箱格式

       //String email = "[email protected]";
    	  String email="myweb/reg?username=xxx&password=xxx&....";
    	  String regex="\\?";
		/*
		 * \w+@[a-zA-Z0-9]+(\.[a-zA-Z]+)+;
		 * 使用字符串描述正则表达式
		 */   
		//String regex="\\w+@[a-zA-Z0-9]+(\\.[a-zA-Z]+)";
		boolean match=regex.equals(email);
		if(match){
			System.out.println("是邮箱");
		}else {
			System.out.println("不是邮箱");
		}

2、 String 支持正则表达式方法二:

  • String[] split(string regex)
  • 将当前字符串按照满足正则表达式的部分进行拆分,
  • 将拆分后的部分以数组形式返回

拆分小例子

       String line = "abc123bcd456efg789hji";
		/*
		 * 按照数字部分拆分,得到所有的字母部分
		 */
		//String []arr1=line.split("[0-9]+");
		
		/**
		 * 如果在拆分中出现了可连接的可拆分项 时,他们中间会拆分一个空字符串。
		 * 如果字符串开始就是拆分项时,前面也会拆分出 一个空字符串
		 * 注意:如果是字符串末尾连续匹配拆分项,那么所有拆分出的空串全部忽略
		 */
		String []arr=line.split("[0-9]");
		System.out.println(arr.length);
		for(int i=0;i<arr.length;i++){
			System.out.println(arr[i]);
		}
		String image ="123.png";
		String []date=image.split("\\.");
		image =date[1];
		System.out.println(image);

3、 String 支持正则表达式三:

  • String replaceALL(String regex ,String str)
  • 将当前字符串中满足正则表达式部分替换为给定内容

替换小例子

        String str1 = "abc123def456ghi789jkl";
		/*
		 * 将数字部分替换为"#NUMBER#"
		 */
		String str = str1.replaceAll("[0-9]+","#NUMBER#");
		System.out.println(str);

4、和谐用语

当使用不文明语句,可以判断是否符合条件,然后进行替换,
例子如下:

    String regex = "(dsb|mdzz|cnm|wqnmlgb)";
	String message = "wqnmlgb!cnm";
	message = message.replaceAll(regex,"**");
	System.out.println(message);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章