String【字符串】

可变字符串和不可变字符串

  不可变字符串序列

    String
   /*

    为不可变对象,一旦被创建,就不能修改它的值
    对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去
    String 是final类,即不能被继承

    并且由于String 对象是不可变对象,每次操作Sting 都会重新建立新的对象来保存新的值
    这样原来的对象就没用了,就要被垃圾回收.这也是要影响性能的 

  */

  可变字符串序列

    StringBuffer:安全性高效率低   安全的synchronized
    StringBuilder:效率高安全性低

  /*   

    是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象
    它只能通过构造函数来建立,
    StringBuffer sb = new StringBuffer();
    note:不能通过赋值符号对他进行赋值. 
    sb = "welcome to here!";//error
    对象被建立以后,在内存中就会分配内存空间,并初始保存一个null.向StringBuffer
    中赋值的时候可以通过它的append方法.

  */

  可变字符串为什么可变?  

    首先创建了一个长度为16的数组,当存放数据的时候,首先检查当前数组是否能够装下当前数据,如果存的下直接存放,如果存不下,数组开始扩容,每次扩大 length*2+2,所以说我们可变字符串序列就是因为数组的大小在一直改变 

<------不可变字符串String------>

特性

public final class String

  字符串在java中是一个类,然后这个类是一个太监类,不能被继承

  final

  这个字符串变量的value值的引用只能被初始化一次,而且引用没法进行修改
  但是数组中的值还是可以被改变的

  private

  string类中没有提供设置数组的方法,禁止外部的修改

  特点

  String的默认值为null

  注意""和null是不同的,""是一个对象,代表没有内容,length为0,但是null代表指向空,运行时会出现“空指针异常”

  String a="abc"; 等同于 String a=new String;

  a是一个类类型变量,abc是一个对象

  字符串最大的特点就是,一旦被初始化就不可以被改变

  对于我们的字符串来讲,如果我们对字符串做了拼接,删除,修改的操作,会重新创建新的字符串

内存视图

内存分析[了解]
  栈
  堆
  方法区
    代码 
    静态变量
    字符串常量池

  池:提供一个可重复使用,减少对象的创建时间
  字符串这种数据类型在日常生活中使用较频繁
  常量池中的字符串对象有可能有多个引用同时指向,如果字符串的值是可变的,那其中一个引用把值给它改变了
  所有的引用看到的结果都是改变后的, 数据的安全性就得不到保证

  就是因为字符串是一个不可变的字符序列,所以每当发生改变的时候都会创建一个新的对象,所以常量池这种机制才能够使用
字符串比较

  变量相加就先创建新的字符串,有独立的地址值 如b1="hello" b2="world" b1+b2!=helloworld
  字符串和字符串相加就是普通的字符串加字符串 如 "hello"+"world" =helloworld

注意:基本数据类型只比较值,地址一不一样无所谓
     引用类型比较地址值

应用

单纯值与值的比较

1 public class TestString {
2 public static void main(String[] args) {
3 
4   String a1 = "abcdef";
5   String a2 = "abcdef";
6 
7  System.out.println(a1 == a2); //true
8 
9 }
 1 public class TestString {
 2 public static void main(String[] args) {
 3 
 4   String b1 = "hello";
 5   String b2 = "world";
 6 
 7   String b3 = "helloworld";
 8   String b4 = "hello" +"world";
 9 
10  System.out.println(b3 == b4); //true  因为只是单纯的字符串和字符串相加,所以比较的是字符串的值
11 
12 }

地址值和地址值的比较

public class TestString {
public static void main(String[] args) {

  String b1 = "hello";
  String b2 = "world";

  String b3 = "helloworld";
  String b4 = b1+"world";

 System.out.println(b3 == b4); //false 因为对对象b1进行了+的操作,地址值发生改变
}

String中的equals比较

 1 public class StringDemo {
 2 public static void main(String[] args) {
 3     String s1="abc";
 4     String s2=new String("abc");
 5     
 6     System.out.println(s1==s2);  //false
 7     System.out.println(s1.equals(s2));  //true
 8 
 9 }
10 }

详细解释

 syso(s1==s2) //false 

  在这句代码中,因为如果对字符串的对象做了拼接,删除,修改的操作,会重新创建新的字符串对象,所以s1和s2比较的是对象的地址值,由于是s1和s2指代的是两个对象,所以返回值为false

 syso(s1.equals(s2))  //true

  在这句代码中,String类重写了Object类中的equals方法,使得该方法判断字符串内容是否相等,由于"abc"="abc",所以返回值为true

延伸

 s1和s2有什么区别?[面试]

  s1内存中有一个对象 "abc"

  s2内存中有两个对象 "new String"和"abc"

String中的常用方法

判断功能

contains(str):查询是否包含指定的字符串

        特殊之处:在indexOf(str)中如果没有所查找的字符或者字符串,会返回-1,所以可以用于对制定字符串是否存在的判断

1 public class TestStringSkill {
2     public static void main(String[] args) {
3 
4         String string = "abcdefghijklMnopqrstuvwxyz中发白中发白";
5      boolean flag = string.contains("abcdef");
6               System.out.println(flag);  //true
7 }
8 }

startsWith:以XXX开头   endsWith:以XXX结尾

 1 public class TestStringSkill {
 2     public static void main(String[] args) {
 3 
 4         String string = "abcdefghijklMnopqrstuvwxyz中发白中发白";
 5      boolean flag = string.startsWith("abcdefghijklmnopqrstuvwxyz");  //必须是从头开始,从第一个字符开始
 6                 System.out.println(flag);  //false
 7                 boolean flag1 = string.endsWith("发白");   //必须是从末尾开始,从最后一个字符开始
 8                 System.out.println(flag1);  //true
 9 }
10 }

equals:返回值boolean类型   判断字符串内容是否相同,重写了Object的equals方法,比较的是字符串的值,并且不忽略大小写

1 public class TestStringSkill {
2     public static void main(String[] args) {
3      String str1 = new String("abcd");
4         String str2 = new String("abcd");
5     System.out.println(str1 == str2);  //false  //比较的是地址值
6     System.out.println(str1.equals(str2));  //true //比较的是字符串的值
7 }
8 }

equalsIgnoreCase():判断内容是否相同,并且忽略大小写

 1 public class StringDemo {
 2     public static void main(String[] args) {
 3         Demo.demo1();
 4     }
 5 }
 6 
 7 class Demo {
 8     public static void demo1() {
 9         String string = "abc";
10         String string2 = "ABC";
11 
12         System.out.println(string.equalsIgnoreCase(string2)); // true
13         System.out.println(string.equals(string2)); // false
14     }
15 }

 

isEmpty():返回值为boolean,判断字符串中是否有内容,如果返回值为true,则length为0

1 public class StringDemo {
2 public static void main(String[] args) {
3     String string="abcdefghijklmn";
4 
5     System.out.println(string.isEmpty()); //false
6 
7 }
8 }

注意""和null是不同的,""是一个对象,代表没有内容,length为0,但是null代表指向空,会出现“空指针异常”

 1 public class StringDemo {
 2 public static void main(String[] args) {
 3     Demo.demo1();  
 4     //Demo1.demo2();  //报空指针异常   java.lang.NullPointerException
 5 }
 6 }
 7 
 8 class  Demo{
 9     public static void demo1() {
10         String string="";
11         
12         System.out.println(string.length());  //0
13         System.out.println(string.isEmpty()); //true
14     }
15 }
16 
17 class Demo1{
18     public static void demo2() {
19         String string=null;
20         
21         System.out.println(string.length());
22         System.out.println(string.isEmpty());
23     }
24 }

获取功能

length:返回当前字符串的长度[int型]

1 public class TestStringSkill {
2     public static void main(String[] args) {
3 
4         String string = "abcdefghijklMnopqrstuvwxyz中发白中发白";
5      System.out.println(string.length());  //32
6 }
7 }

charAt(int index),根据位置获取位置上的某个字符,从0开始计数,当访问到字符串中不存在的角标时会出现StringIndexOutOfBoundsException

1 public class TestStringSkill {
2     public static void main(String[] args) {
3 
4         String string = "abcdefghijklMnopqrstuvwxyz中发白中发白";
5         char c = string.charAt(1);
6         System.out.println(c);  //b
7 }
8 }

codePointAt:char类型的字符对应的编码值[ASCII码 阿斯克码]

 1 public class TestStringSkill {
 2     public static void main(String[] args) {
 3 
 4         String string = "abcdefghijklMnopqrstuvwxyz中发白中发白";
 5                 int i = string.codePointAt(26);
 6                 int i1 = string.codePointBefore(27);
 7                 int i2 = string.codePointCount(0, 26);
 8                 System.out.println(i);    //20013
 9                 System.out.println(i1);  //20013
10                 System.out.println(i2);  //26
11     }
12 }

 

hashCode:获取对象的哈希值,如果两个对象equals那么他们的hashcode一定相同,但hashcode相同不一定equals

1 public class TestStringSkill {
2     public static void main(String[] args) {
3        String str1 = new String("abcd");
4         String str2 = new String("abcd");
5       System.out.println(str1.hashCode());   //2987074
6         System.out.println(str2.hashCode()); //2987074
7 }
8 }

indexOf(int ch):返回当前字符串所在的索引值[位置],返回的是ch字符在字符串中第一次所出现的位置

indexOf(String ch):返回当前字符串所在的索引值[位置],返回的是ch字符串在字符串中第一次所出现的位置

注意:如果没有所查找的字符或者字符串,会返回-1,所以可以用于对制定字符串是否存在的判断

 1  public class TestStringSkill {
 2      public static void main(String[] args) {
 3     String string = "abcdefghijklMnopqrstuvwxyz中发白中发白";
 4                  int i = string.indexOf("b");
 5                  int i1 = string.indexOf(122);
 6                  int i2 = string.lastIndexOf("中");
 7                  System.out.println(i);  //1
 8           System.out.println(i1);  //25
 9           System.out.println(i2);  //29
10      }
11   }    

indexOf(int ch,int fromIndex):从fromIndex指定位置开始,获取字符ch在字符串中出现的位置

indexOf(String ch,int fromIndex):从fromIndex指定位置开始,获取字符串ch在字符串中出现的位置

注意:如果没有所查找的字符或者字符串,会返回-1,所以可以用于对制定字符串是否存在的判断

 1 public class StringDemo {
 2 public static void main(String[] args) {
 3     String string="abcdefghijklmn";
 4     
 5     int i=string.indexOf("i", 5);
 6     int i1=string.indexOf("jk", 5);
 7     
 8     System.out.println(i); //8
 9     System.out.println(i1); //9
10 }
11 }

lastIndexOf(int ch):返回当前字符串所查的字符最后面所在位置的索引值

lastIndexOf(String ch):返回当前字符串所查的字符最后面所在位置的索引值

1 public class TestStringSkill {
2      public static void main(String[] args) {
3      String string = "abcdefghijklMnopqrstuvwxyz中发白中发白";
4               
5                   int i2 = string.lastIndexOf("中");
6         
7            System.out.println(i2);  //29  //返回的是最后面的中所在的索引值
8       }
9    }    

 

转换功能

将字符数组转换为字符串

  构造函数:String(char[]) :将字符数组的全部内容转成字符串

         String(char[],offset,count) :将字符数组的一部分转成字符串   offset:起始位置  count:取得个数

 1 public class StringDemo1 {
 2 public static void main(String[] args) {
 3     char[] arr={'a','b','c','d','e','f','g'};
 4     
 5     String string=new String(arr);
 6     
 7     System.out.println(string);  //abcdefg
 8 
 9 }
10 }
 1 public class StringDemo1 {
 2 public static void main(String[] args) {
 3     char[] arr={'a','b','c','d','e','f','g'};
 4     
 5     String string=new String(arr,2,3);
 6     
 7     System.out.println(string);  //cde
 8 
 9 }
10 }

将字节数组转换为字符串

  构造函数:String(byte[]) :将字符数组的全部内容转成字符串

         String(byte[],offset,count) :将字符数组的一部分转成字符串   offset:起始位置  count:取得个数

 1 public class StringDemo1 {
 2     public static void main(String[] args) {
 3         byte[] arr = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
 4 
 5         String string1 = new String(arr);
 6 
 7         String string = new String(arr, 2, 3);
 8 
 9         System.out.println(string); //
10         System.out.println(string1); // abcdefg
11 
12     }
13 }

toCharArray():将字符串转成字符数组

 1 public class StringDemo1 {
 2     public static void main(String[] args) {
 3         String string = "abcdefg";
 4 
 5         char[] arr = string.toCharArray();
 6         for (int i = 0; i < arr.length; i++) {
 7             System.out.println(arr[i]);
 8             //a b c d e f g
 9         }
10 
11     }
12 }

getBytes:将字符串转换成字节数组

   注意:字符串和字节数组在转换过程中是可以指定编码表的

 1  public class TestStringSkill {
 2      public static void main(String[] args) {
 3     String string = "abcdefghijklMnopqrstuvwxyz中发白中发白";
 4      byte[] bytes = string.getBytes();   
 5       for (int i = 0; i < bytes.length; i++) 
 6         { 
 7           System.out.print(bytes[i]+" "
 8 
 9         }; 
10 
11 输出:97 98 99 100 101 102 103 104 105 106 107 108 77 110 111 112 113 114 115 116 117 118 119 120 121 122 -42 -48 -73 -94 -80 -41 -42 -48 -73 -94 -80 -41
12 
13 注意:此方法不可以用于中文,否则会出现负数

替换功能

replace(oldchar,newchar):替换,退还之后相当于返回一个新的字符串,原字符串不改变

1 public class StringDemo1 {
2     public static void main(String[] args) {
3 
4         String string = "abcdefghijklMnopqrstuvwxyz中发白中发白";
5         String newstring = string.replace("abc", "_");
6         System.out.println(newstring); // _defghijklMnopqrstuvwxyz中发白中发白
7         System.out.println(string); // abcdefghijklMnopqrstuvwxyz中发白中发白
8     }
9 }

切割操作

split:切割/拆分字符串

 1 public class TestStringSkill {
 2     public static void main(String[] args) {
 3 
 4         String string = "abcdefghijklMnopqrstuvwxyz中发白中发白";
 5      String[] ss = string.split("xyz");   //从xyz开始拆分   xyz不会显示   注意要定义为数组,因为结果是两组数据
 6          for (int i = 0; i < ss.length; i++) {
 7          System.out.println(ss[i]); //abcdefghijklMnopqrstuvw
 8                                       中发白中发白
 9                 }
10 }
11 }

字串

substring(begin,end) :截取字符串,如果角标不存在,会出现角标越界异常

substring(begin)::截取字符串 ,如果角标不存在,会出现角标越界异常

 1 public class StringDemo1 {
 2     public static void main(String[] args) {
 3 
 4         String string = "abcdefghijklMnopqrstuvwxyz中发白中发白";
 5         String news = string.substring(1, 5); // 注意(1,5)代表1到5,包含1,不包含5
 6         String news1 = string.substring(1, string.length());
 7         String news2 = string.substring(1);
 8 
 9         System.out.println(news); // bcde
10         System.out.println(news1); // bcdefghijklMnopqrstuvwxyz中发白中发白
11         System.out.println(news2); // bcdefghijklMnopqrstuvwxyz中发白中发白
12     }
13 }

转换、去除空格、比较功能

toLowerCase/toUpperCase:转换为大小写

1 public class TestStringSkill {
2     public static void main(String[] args) {
3   System.out.println(string.toLowerCase() + "----" +   string.toUpperCase());    //abcdefghijklmnopqrstuvwxyz中发白中发白----ABCDEFGHIJKLMNOPQRSTUVWXYZ中发白中发白
4 
5     }
6 }

trim:去掉前后两端的空格

1 public class StringDemo1 {
2     public static void main(String[] args) {
3         String string4 = "      Hello Bjsxt           ";
4         System.out.println(string4.trim()); //Hello Bjsxt
5     }
6 }

compareTo:比较两个字符串的大小 大于正数  小于负数 相等0 ,考虑大小写,而且小写字母比大写字母大  

       一个一个字符,比较的是ASCII码

1 public class TestStringSkill {
2     public static void main(String[] args) {
3         String string1 = "a";
4       String string2 = "A";
5         System.out.println(string1.compareTo(string2));       //32  比较,不忽略大小写
6         System.out.println(string1.compareToIgnoreCase(string2));  //0   比较,忽略大小写
7 }
8 }

连接字符串功能

concat:连接字符串,但会创建一个新的字符串并返回

1 public class TestStringSkill {
2     public static void main(String[] args) {
3 
4         String string = "abcdefghijklMnopqrstuvwxyz中发白中发白";
5         String ss = string.concat("东南西北");
6         System.out.println(ss == string);  //false
7 }
8 }

<------可变字符串StringBuffer/StringBuilder------>

StringBuffer

  字符串缓冲区,是一个容器

  (1)长度是可以变化的

  (2)可以直接操作多个数据类型

  (3)最终会通过toString方法变成字符串

C create   U update  R read  D delete

  1.存储

    StringBuffer append():将指定数据作为参数添加到已有数据的结尾处

    因为时容器,所以stringBuffer和stringBuffer1指向的是同一个对象,所以相等

写法一

 1 public class Exam1 {
 2     public static void main(String[] args) {
 3         StringBuffer stringBuffer = new StringBuffer();
 4         stringBuffer.append("ABC");
 5         stringBuffer.append(true);
 6 
 7         StringBuffer stringBuffer1 = stringBuffer.append(1);
 8 
 9         System.out.println(stringBuffer == stringBuffer1); // true
10         System.out.println(stringBuffer.toString); // ABCtrue1
11         System.out.println(stringBuffer1.toString); // ABCtrue1
12     }
13 }

写法二[方法调用链]

1 public class Exam1 {
2     public static void main(String[] args) {
3         StringBuffer stringBuffer = new StringBuffer();
4 
5         stringBuffer.append("ABC").append(true).append(1);
6 
7         System.out.println(stringBuffer.toString); // ABCtrue1
8     }
9 }

StringBuffer insert(index,数据):可以将数据插入到指定index位置,从index的位置开始插入

 1 public class Exam1 {
 2     public static void main(String[] args) {
 3         StringBuffer stringBuffer = new StringBuffer();
 4 
 5         stringBuffer.append("ABC").append(true).append(1);
 6 
 7         stringBuffer.insert(1, "MM");
 8         System.out.println(stringBuffer.toString()); // AMMBCtrue1
 9     }
10 }

  2.删除

  StringBuffer.delete(int start,int end):删除缓冲区中的数据,包含start,不包含end

  StringBuffer.deleteCharAt(index):删除指定位置的字符

  清空  StringBuffer.delete(0,StringBuffer.length)   我、因为不包含end所对应的位置,所以是length而不是length-1

  删除一个字符   StringBuffer.delete(x,x+1);    StringBuffer.deleteCharAt(x);

 1 public class Exam1 {
 2     public static void main(String[] args) {
 3         delete();
 4     }
 5 
 6     public static void delete() {
 7         StringBuffer stringBuffer = new StringBuffer("abcde");
 8         // 删除包含1不包含3的位置字符
 9         // stringBuffer.delete(1, 3);
10         // System.out.println(stringBuffer); // ade
11 
12         // 清空缓冲区
13         // stringBuffer.delete(0, stringBuffer.length());
14         // System.out.println(stringBuffer.toString());
15 
16         // 删除一个字符
17         stringBuffer.delete(2, 3); // abde
18         // stringBuffer.deleteCharAt(2); //abde
19         System.out.println(stringBuffer.toString()); // abde
20     }
21 }

  3.获取

  char charAt(int index):获取指定索引位置的值

  int indexOf(String str):返回指定字符串在字符串中第一次出现的位置

  int lastIndexOf(String str):返回指定字符串在字符串中最后一次出现的位置

  length():返回长度信息

  String substring(int start,int end)  注意这个方法还是用String不是用StringBuffer:截取字符串  [x,y)

 1 public class Exam1 {
 2     public static void main(String[] args) {
 3         search(new StringBuffer("ABCDEFAG"));
 4     }
 5 
 6     public static void search(StringBuffer stringBuffer) {
 7         
 8         
 9         System.out.println(stringBuffer.charAt(2));  //C
10         System.out.println(stringBuffer.indexOf("D")); //3
11         System.out.println(stringBuffer.lastIndexOf("A")); //6
12          
13         System.out.println(stringBuffer.length()); //8
14         
15         String string=new String("ABCDEFAG");
16         
17         System.out.println(string.substring(1,3));  //BC
18     }
19 }

  4.修改

   StringBuffer.replace(int start,int end,String str):替换指定位置内容[是改变原字符串,不新建字符串]

   StringBuffer.setCharAt(index,char ch):修改一个位置的一个字符

   StringBuffer.reverse:反转当前字符串

   StringBuffer.getChars(int srcBegin,int srcEnd,char[] dst,int dstBegin):将缓冲区中指定数据存储到指定字符数组中

               字符起始位置    字符结束位置        数组  数组存储启示位置

 1 public class Exam1 {
 2 public static void main(String[] args) {
 3     StringBuffer stringBuffer=new StringBuffer("ABCDEFG");
 4 
 5     Test test=new Test();
 6     test.demo(stringBuffer);
 7 }
 8 }
 9 
10 class Test{
11     
12     public static void demo(StringBuffer stringBuffer) {
13         stringBuffer.replace(1, 4, "H"); // [1,4)
14 
15         System.out.println(stringBuffer); // AHEFG
16 
17         stringBuffer.setCharAt(2, 'M');
18         System.out.println(stringBuffer); // ABMDEFG
19 
20         stringBuffer.reverse();
21         System.out.println(stringBuffer); // GFEDCBA
22         
23         char []abc=new char[10];
24         
25         stringBuffer.getChars(1, 4, abc, 1);
26         
27         System.out.println(abc); // BCD      ;
28     
29     }
30 }

StringBuilder[和StringBuffer功能一样]

JDK1.5版本之后出现了StringBuilder

区别:

  StringBuffer:线程同步,安全

  StringBuilder:线程不同步,不安全

推荐:多线程StringBuffer   单线程StringBuilder

   以后开发建议使用StringBuilder,效率高

JAVA升级三因素:

  1.提高效率

  2.简化书写

  3.提高安全性

posted @ 2016-08-03 20:52  IT蓄水池  阅读(350)  评论(0)    收藏  举报