JavaSE------字符串

1.构建字符串

        String str1="abcdefg";//把字符串放到堆上面的字符串常量池里面了
        String str2=new String("abcdefg");
        char[] arr1={'a','b','c'};
        String str3=new String(arr1);
字符串类型是 public final class String extends Object,他是不可变常量,是不可以被继承的

下面我们来看一下 String str=new String("hello")的内存布局;

2.字符串比较相同

1)我们在使用==比较字符串的时候并不是在进行比较字符串的内容,而是在比较两个引用是否指向了同一个对象

 String str1="hello";
        String str2="hello";
        System.out.println(str1==str2);//str1与str2都会被放到字符串常量池里面,所以他们的引用是相同的
        String str3=new String("hello");
        String str4=new String("hello");
        System.out.println(str3==str4);//字符串的内容虽然相同,但是new String("hello")都会在堆上面开辟内存
        System.out.println(str1==str3);

 

 2)所以我们在java中比较两个字符串是否相同,就要用到String类提供的equals方法

       String str1=new String("hello");
       String str2=new String("hello");
       System.out.println(str1.equals(str2));//打印的结果是false
//下面是equals方法使用的一个注意事项
  String str1=new String("hello");
    System.out.println(str1.equals("hello"));
    System.out.println("hello".equals(str1));
    //我们此时更推荐的做法是方法二,一旦str是null,那么str1是null,那么代码1会抛出异常,但是代码2不会

  String str1="hello";
      String str2="hell"+"o";
      String str3="he";
      String str4=str3+"llo";
      System.out.println(str1==str2);//true
      System.out.println(str2==str4);//false
        //在str2中,"he"与"llo"都是常量,编译的时候就会自动编译成”hello";
        //但是在str4这个变量中str3是一个变量,编译器根本就不知道str3具体的值

3)手动入池

String str1=new String("hello").intern();
  String str2="hello";
  System.out.println(str1==str2);//打印结果是false
String str = "a"+"b"+"c"+"d";一共创建了几个对象?
该代码会被编译器编译时优化成"abcd",所以相当于String str = "abcd",所以只创建了一个对象
字符串常量池存于堆内存中(1.8之前是方法区)。
常见的常量池:
1)class文件常量池:
int a=10;这是磁盘上面的
2)运行时常量池:当程序把编译好的字节码文件,加载到JVM之后,会生成一个运行时常量池,他在方法去里面,实际上是class文件常量池

3.String中的一些常见方法

1)字符与字符串

 //1字符数组变成字符串
        char[] arr1={'a','b','c'};
        String str=new String(arr1);
  //2将部分字节数组的内容变成字符串
  String hh=new String(arr1,1,3);    
  //3字符串变成数组
 String str2="world";
  char[] arr2=str2.toCharArray();     
  //4获取到固定位置的索引的字符
        String dd=new String("lijiawei");
        char ch=dd.charAt(1);

2)字节与字符串

 //1字节数组转化成字符串
  byte[] arr1={12,34,5,6,7};
  String str=new String(arr1)
//2字符串转化成字节数组
 String str1="abcdefgh";
  byte[] arr=str1.getBytes();
/3忽略大小写的比较
String str1="abcdefg";
String str2="ABCDEFG";
System.out.println(str1.equalsIgnoreCase(str2));
//4 比较字符串的长度
String str3="abcdefg";
String str4="abcdef";
//str1>str2返回的是正数;str1==str2返回的是0;str1<str2返回的是负数
System.out.println(str1.compareTo(str2));

3)字符串的其他方法

//1字符串的替换
String str1="ababababababpppphhh";
String ret=str1.replace("ab","123");//这回创建一个新的对象
//替换首个指定字符的字符串
        ret=str1.replaceFirst("ab","123");
        System.out.println(ret);
//2字符串的截取
String str1="Hello";
String ret=str1.substring(1);//从一号位置开始进行截取,截取后面的字符串
System.out.println(ret);//打印出来的值是llo
ret=str1.substring(1,4);[1,4)从一号位置到四号位置进行字符串的截取
//3去掉字符串两边的空格,但是不可以去掉字符串中间的空格
 String str1=" abcdef gh ";
 String ret=str1.trim();
 System.out.println(ret);
//4查找指定的字符串在原字符串的位置
String str1="abcdefg";
int index=str1.indexOf("abc");
int num=str1.indexOf("def");
System.out.println(index);
System.out.println(num);
//5查找目标字符串是否在源字符串之内
String str1="abcdef";
boolean flag=str1.contains("abcdef");
System.out.println(flag);//打印结果是true

4)字符串进行查找

//1从某个位置开始找
 String str1="abcdefghabcdefgh";
 int index=str1.indexOf("def",2);//从2号位置开始查询def所在的位置
 System.out.println(index);//打印结果是3
 //2从后面向前面找     
 index=str1.lastIndexOf("abc");
 System.out.println(index);//打印结果是8
//3判断某个字符串是否以xx开头
String str="abcdef";
boolean flag=str.startsWith("ab");
System.out.println(flag);
//4判断某个字符串是否以指定的偏移量开始
String str="abcdefg";
boolean flag=str.startsWith("abc",0);
System.out.println(flag);
//5判断某个字符串是否以xx结尾
String str1="abcdefg";
boolean flag=str.endswith("abc");
System.out.println(flag);//false;

5)有关于字符串的拆分---返回值是一个字符串数组

1)String str1="abc de f";
String arr1[]=str1.split(" ",2);
for(String ret:arr1)
{
    System.out.println(ret);
}
//如果split()后面加上了一个参数2,那么此时返回的字符串就会分成两组,一组是abc,一组是de f;
如果不加上2这个参数或者说压根就没有参数,此时就会默认分成三组,一组是abc,一组是de,一组是f;
2)String str1="name=zhangsan&age=19";
String[] arr1=str1.split("&");
for(String[] ret: arr1)
{
     String[] ss= ret.split("=");
     for(String sss:ss)
     {   
          System.out.println(sss);
      }
}
3)String str1="127.0.0.1";
String[] strings=str1.split("\\.");
//.号这个字符编译器是无法认清的,所以我们要通过/来进行转义,但是我们还需要对/来进行转义,所以要再加上一个/
for(String hh:strings)
{
    System.out.println(hh);
}

    }
}
4)字符"|","*","+",前面加上"\"
如果是"",里面就要写上\\
  String str1="127*0*0*1";
        String[] strings=str1.split("\\*",7);
//.号这个字符编译器是无法认清的,所以我们要通过/来进行转义,但是我们还需要对/来进行转义,所以要再加上一个/
        for(String hh:strings)
        {
            System.out.println(hh);
        }

    }
5)str2="127\\0\\0\\1",这时候分割就要写四个\
String str2="127\\0\\0\\1";
  String[] arr1=str2.split("\\\\");
  for(String ret:arr1)
  {
      System.out.println(ret);
  }
6)
String str1="java300 12&31#hello";
  String[] strings=str1.split(" |&|#");
  for(String str:strings)
  {
      System.out.println(str);
  }
7) String str1="abcdef";
  String str2=str1.toUpperCase();//将小写字母全部变成大写字母,同理str1.toLowerCase是把所有的的大写字母变成小写字母
  System.out.println(str2);
8)判断字符串是否为空.isEmpty()方法
9)contat()方法,出字符串常量池
intern()方法,手动入池,表示最后拼接的对象不会进入到常量池里面,会new一个新的对象
String str1="hello".concat("1");
 String str2="hello1";
 System.out.println(str1==str2);//false

在这里面我们要注意String str1="";表示这个str1的引用指向一个空字符串,String str2=null,表示str2不会指向任何对象

3.StringBuilder与StringBuffer

1)String类与StringBuffer的类最大的区别就是String的内容无法进行修改,但是StringBuffer的内容是可以进行修改的,所以我们在频繁的修改字符串的时候优先考虑StringBuffer

StringBuilder stringBuilder=new StringBuilder("hello");
     StringBuilder  str=stringBuilder.append("world");
        System.out.println(str==stringBuilder);
        String str1="hello";
        String str2="hello"+"world";
        System.out.println(str1==str2);

2)String的拼接会产生大量的临时对象,所以我们是不可以循环进行拼接的,但是StringBuffer和StringBuilder会返回当前对象的引用

3)普通的String字符串拼接会被优化成StringBuilder

4) StringBuffer对象则代表一个字符序列可变的字符串,当一个StringBuffer被创建以后,通过StringBuffer提供的append()、insert()(将指定的字符集插入到指定位置)、reverse()、setCharAt(),delete(a,b)(删除指定位置区间的字符)等方法可以改变这个字符串对象的字符序列。一旦通过StringBuffer生成了最终想要的字符串,就可以调用它的toString()方法将其转换为一个String对象。
5)StringBuffer是线程安全的,StringBuilder是线程不安全的

猜你喜欢

转载自blog.csdn.net/weixin_61518137/article/details/125091641