java:String详解(转)

 

1、String的常见创建方式:

        //方式一
        String str1="hello";  //这种用的最多
        
        //方式二
        String str2=new String("hello");
        
        //方式三
        char[] ch={'h','e','l','l','o'};       
        String str3=new String(ch);
        
        //方式四
        String str4=new String("hello").intern();//intern()方法先在常量池里查找,
        要是有值为hello的字符串,//则不新建,将地址指向。要是没有则在常量池里新建一个。所以相等。

 

 

2、字符串比较:

==比较内存。equals比较内容

1、==比较

String str1 = "Hello";
String str2 = "Hello";
System.out.println(str1 == str2);
// 执行结果
true 

俩都在字符串常量池的,str1 和str2指向同一个对象,是==

String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1 == str2);
// 执行结果
false

俩都是在堆上开辟内存,所以是指向不同的堆地址,false

 String str3=new String("hello");
 String str4=new String("hello").intern();//intern()方法先在常量池里查找,要是有值为hello的字符串,//则不新建,将地址指向。要是没有则在常量池里新建一个。所以相等。
  System.out.println(str1 == str2);
// 执行结果
true

// 执行结果 true 反之,要是先str4,后str3,则不相等

 

2、equals比较

 

String的equals实际上是重写了Object的equals方法,才实现了String的内容的比较


String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1.equals(str2));
// 执行结果
true

String的equals的注意事项:

调用.equals的部分不能为null,不然抛出异常

String str = null;
// 方式一
System.out.println(str.equals("Hello"));  
// 执行结果 抛出 java.lang.NullPointerException 异
常
// 方式二
System.out.println("Hello".equals(str));  // 执行结果 false

3、字符串常量池

String类的设计使用了共享设计模式(可以理解为现在的共享单车,如果我们想用的话就在外面直接扫一辆单车直接用就行了(从常量池中取),不用我们再买一辆新的自行车(自己new一个新的对象赋值),大大方便了我们的使用)

在JVM底层实际上会自动维护一个对象池(字符串常量池)

  • 如果现在采用了直接赋值的模式进行String类的对象实例化操作,那么该实例化对象(字符串内容)将自动保存到这个对象池之中.
  • 如果下次继续使用直接赋值的模式声明String类对象,此时对象池之中如若有指定内容,将直接进行引用。
  • 如若没有,则开辟新的字符串对象而后将其保存在对象池之中以供下次使用

我们一般采取直接赋值的方式创建 String 对象

String str1 = "Hello";
String str2 = "Hello";
System.out.println(str1 == str2);
的结果为true。

这块也就解释了,第一次的时候,在常量池维护了“hello”,第二次直接“拿”了。所以是同一份“hello”

 

4、字符串不可变

String类底层是char[]实现的,String 类的内部实现也是基于 char[] 来实现的, 但是 String 类并没有提供 set 方法之类的来修改内部的字符数组。

String str = "hello" ;
System.out.println(str.hashCode());
str = str + " world" ;
str += "!!!" ;
System.out.println(str);
System.out.println(str.hashCode());

执行结果
99162322
hello world!!!
1640396477

 

表象上看,str是执行了 +=的操作。但其实是生成了新的String,其地址已经发生改变,hashCode值发生改变,底层原理是在字符串常量池新申请了一块内存,其值为+=操作后的值,引用到str。

如果必须实现修改字符串

 

1)常见办法: 借助原字符串, 创建新的字符串

String str = "Hello";
str = "h" + str.substring(1);
System.out.println(str);
// 执行结果
hello

2)反射

使用 “反射” 这样的操作可以破坏封装, 访问一个类内部的 private 成员

 

为什么 String 要不可变?(不可变对象的好处是什么?)

  • 方便实现字符串对象池. 如果 String 可变, 那么对象池就需要考虑何时深拷贝字符串的问题了.
  • 不可变对象是线程安全的.
  • 不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中

 

5、字符、字节与字符串

1、字符串内部包含一个字符数组,String可以和char[]相互转换

常用方法

    • toCahrArray()将字符串转换为char数组并返回
    • charAt(index)截取一个字符
    • String()数组转为字符串
    • valuesOf(char[])数组转字符串
    • copyValueOf(char[])数组转字符串

2、字节与字符串

字节常用于数据传输以及编码转换的处理之中,String 也能方便的和 byte[] 相互转换(一般在网络方面使用)

常用的一些方法

  • getBytes()将字符串以字节数组的形式返回
  • getBytes(String charsetName)throws UnsupportedEncodingException编码转换处理

 

6、字符串常见的操作

可参考 java String类的常用方法

1、字符串比较

字符串比较

  • equals()和equalsIgnoreCase() 比较两个字符串(ignore不区分大小写)
  • compareTo()和compareToIgnoreCase() 比较字符串

字符串查找

  • 字符串查找,最好用最方便的就是contains()
  • startsWith()方法判断是否以指定字符开头
  • endWith()方法决定是否以指定字符结尾
  • indexOf() 查找字符或者子串第一次出现的地方。
  • lastIndexOf() 查找字符或者子串是后一次出现的地方

字符串替换

  • replaceAll() 替换所有指定内容
  • replaceFirst()替换首个内容

注意事项: 由于字符串是不可变对象 , 替换不修改当前字符串, 而是产生一个新的字符串

字符串拆分

  • split(String regex)将字符串全部拆分
  • split(String regex,int limit)将字符串部分拆分,切分该数组长度的就是limit的最大值

拆分是特别常用的操作. 一定要重点掌握. 另外有些特殊字符作为分割符可能无法正确切分, 需要加上转义.

String str = "192.168.1.1" ;
String[] result = str.split("\\.") ;
for(String s: result) {
 System.out.println(s);
} 

注意事项:

  1. 字符" | “,” * “,”+“都得加上转义字符,前面加上”\ ".
  2. 而如果是"\ “,那么就得写成”\".
  3. 如果一个字符串中有多个分隔符,可以用"|"作为连字符.

多次拆分

String str = "name=zhangsan&age=18" ;
String[] result = str.split("&") ;
for (int i = 0; i < result.length; i++) {
 String[] temp = result[i].split("=") ;
 System.out.println(temp[1]);
} 
运行结果
zahngsan

split(String regex,int limit)

        String str = "aaaaaa=bbbbbb=cccccc=ddddd" ;
        String[] strings=str.split("=",2);
        for(int i=0;i<strings.length;i++) {
            System.out.println(strings[i]);
        }
运行结果为
aaaaaa
bbbbbb=cccccc=ddddd

limit给2的话数组的长度便会是2(会切分为两部分

 

字符串截取

从一个完整的字符串之中截取出部分内容。可用方法如下

  • String substring(int beginIndex)从指定索引截取到结尾 String
  • substring(int beginIndex,int endInx)截取部分内容
String str = "helloworld" ;
System.out.println(str.substring(5));
System.out.println(str.substring(0, 5));
输出结果
world
hello

 

 

注意事项:

  • 索引从0开始
  • 注意左闭右开的写法, substring(0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标

其他常用的方法

  • String trim()去掉字符串中的左右空格,保留中间的空格
  • String toUpperCase()字符串转大写
  • String toLowerCase()字符串转小写
  • public native String intern()字符串入池
  • String concat(String str)字符串连接,等同于“+‘’ 但不入池
  • int length()取字符串的长度
  • boolean isEmpty()判断是否为空字符串,但不是null,而是长度为0

 

7、String、StringBuffer 和 StringBuilder

 

String类的特点:

任何的字符串常量都是String对象,而且String的常量一旦声明不可改变,如果改变对象内容,改变的是其引用的指向而已。通常来讲String的操作比较简单,但是由于String的不可更改特性,为了方便字符串的修改,提供StringBuffer和StringBuilder类。

 

1、String、StringBuffer 和 StringBuilder之间的转换

注意:String和StringBuffer类不能直接转换。如果要想互相转换,可以采用如下原则:(String和StringBuilder类似)

  • String变为StringBuffer:利用StringBuffer的构造方法或append()方法

StringBuffer定义了三个构造函数:

  StringBuffer()

  StringBuffer(int size)

  StringBuffer(String str)

  StringBuffer(CharSequence chars)

  • StringBuffer变为String:调用toString()方法

 

2、String、StringBuffer 和 StringBuilder之间的区别

String 和 StringBuilder StringBuffer 区别:

  • 后两者包含了一些String没有的方法 比如reverse方法
  • 后两者是可变的,String是不可变的。String的每次拼接,都会产生新的对象,后两者每次的拼接都返回的是this
  • StringBuilder 之间 StringBuffer 区别:

StringBuilder和String 出现在单线程情况下

StringBuffer因为有synchronized关键字 所以一般出现多线程情况下。

  • StringBuilder和 String之间有啥区别!!

String的拼接 + 会被优化 优化为StringBuilder . append了 !!!

在循环当中 不可以使用String直接进行拼接 这样会产生大量的临时对象(包括优化之后StringBuilder对象)

Java中String知识总结

感谢大佬详细总结 【抱拳】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值