Java三大特殊类之----String类

String类

1.实例化方式 

  • 直接赋值
String str = "Hello";  //str是一个对象,那么Hello就应该保存在堆内存中
System.out.println(str);

这种直接赋值的方法最常用,但是string类毕竟是一个类,即然是类就有构造方法,string类的其中一种构造方法如下: 

  •  传统方法(构造方法):
String str = new String("Hello");
System.out.println(str);

 构造方法需要使用关键字new进行对象实例化

2. 字符串相等比较

1. 对于基本数据类型来说,比较相等可以用 == 号.

2.对于引用类型String类来说,有两种可以比较的方式,那它们有什么区别呢?

  • 观察字符串==比较 
String str1 = "Hello";
String str2 = new String("Hello");
System.out.println(str1 == str2);  //false

str1是直接赋值的方法,而str2是进行了对象实例化 

 为什么结果会是false呢?保持疑问,继续往下看,来看如下内存图分析

==进行的是数值比较,如果用于对象比较,那么它所比较的应该是对象所在地址数值的大小,并没有比价内容,如图,很明显两个"Hello"对象的地址不一样,所以它们不相等

那么如果想进行 两个字符串内容的比较,则必须采用String类提供的equals()方法

  • 使用equals()方法进行内容比较
String str1 = "Hello" ;
String str = new String("Hello") ;
System.out.println(str1.equals(str));

 扩展:

  • 因为String类覆写了equals()方法,所有String.equals可以比较两个字符串内容相等
  • Object类的equals()方法,比较的是两个字符串的内容
  • ==始终比较的是两个变量的地址

 3. String的匿名对象

观察字符串常量

String str1 = "Hello" ;
String str = new String("Hello") ;
System.out.println(str1.equals(str));
System.out.println("Hello".equals(str));//这个Hello是一个字符串匿名对象
                                        //匿名对象保存在堆内存中

 那么在之前出现的String str = "Hello";,本质上就是讲一个匿名的String类对象设置名字,而且匿名对象一定保存在堆内存中

4. 两种实例化方式的区别

1.采用直接赋值:

String str1 = "hello" ;
String str2 = "hello" ;
String str3 = "hello" ;
System.out.println(str1 == str2); // true
System.out.println(str1 == str3); // true
System.out.println(str2 == str3); // true

从图上可以看出str1,str2,str3都同时指向了"hello",为什么没有开辟新的堆内存空间呢?

String类的设计使用了共享设计模式

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

所谓的对象池就是一个对象数组(目的就是减少开销) 

2. 采用构造方法

类对象使用构造方法实例化是标准做法。分析如下程序:

String str = new String("hello") ;

通过分析可知,如果使用String构造方法就会开辟两块堆内存空间,并且其中一块堆内存将成为垃圾空间。除了这
一缺点之外,也会对字符串共享产生问题。

观察字符串共享问题

// 该字符串常量并没有保存在对象池之中
String str1 = new String("hello") ;
String str2 = "hello" ;
System.out.println(str1 == str2); // false

在String类中提供有方法入池操作 public String intern() ;
观察入池操作

String str1 = new String("hello").intern() ;
String str2 = "hello" ;
System.out.println(str1 == str2); // true

总结String类两种对象实例化的区别:

  • 直接赋值:只会开辟一块堆内存空间,并且该字符串对象可以自动保存在对象池中以供下次使用
  • 构造方法:会开辟两块堆内存空间,其中一块称为垃圾空间,不会自动保存在对象池中,可以使用Intern()方法手工入池

一般采用直接赋值的方法

5. 字符串不可变更

字符串一旦定义不可改变

观察如下代码:

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

以上字符串的变更时对象的变更而非字符串常量

可以发现字符串上没有发生任何变化,但是字符串对象的引用一直在改变,而且会形成大量的垃圾空间。

6. 字符与字符串

字符可以转换为字符串,字符串也可以转换为字符

String str = "helloworld" ;
// 将字符串变为字符数组
char[] data = str.toCharArray() ;
for (int i = 0; i < data.length; i++) {
    data[i] -= 32 ;
    System.out.print(data[i]+"、");
 }
// 字符数组转为字符串
System.out.println(new String(data)); // 全部转换
System.out.println(new String(data,5,5)); // 部分转换

 7. 字节与字符串

字节数组可以转换为字符串,字符串也可以转换为字节数组

实现字节数组与字符串的转换

String str = "helloworld" ;
byte[] data = str.getBytes() ;
for (int i = 0; i < data.length; i++) {
   data[i] -= 32 ;
   System.out.print(data[i]+"、");
}
System.out.println(new String(data));

通过程序可以发现,字节并不适合处理中文,只有字符适合处理中文。按照程序的概念来讲,一个字符等于两个字
节。字节只适合处理二进制数据。

8. 字符串比较

除了equals()方法还有一种能够进行区分大小写相等的方法

不区分大小写比较

String str1 = "hello" ;
String str2 = "Hello" ;
System.out.println(str1.equals(str2)); // false
System.out.println(str1.equalsIgnoreCase(str2)); // true

 在String类中compareTo()方法是一个非常重要的方法,该方法返回一个整型,该数据会根据大小关系返回三类内
容:
1. 相等:返回0.
2. 小于:返回内容小于0.
3. 大于:返回内容大于0。

观察compareTo()比较

System.out.println("A".compareTo("a")); // -32
System.out.println("a".compareTo("A")); // 32
System.out.println("A".compareTo("A")); // 0
System.out.println("AB".compareTo("AC")); // -1
System.out.println("刘".compareTo("杨"));

 compareTo()是一个可以区分大小关系的方法,是String方法里是一个非常重要的方法

9. 字符串查找

 字符串查找,最好用最方便的就是contains() 

String str = "helloworld" ;
System.out.println(str.contains("world")); // true

使用indexOf()方法进行位置查找

String str = "helloworld" ;
System.out.println(str.indexOf("world")); // 5,w开始的索引
System.out.println(str.indexOf("bit")); // -1,没有查到
  if (str.indexOf("hello") != -1) {
     System.out.println("可以查到指定字符串!");
}

使用indexOf()需要注意的是,如果内容重复,它只能返回查找的第一个位置

判断开头或结尾

String str = "**@@helloworld!!" ;
System.out.println(str.startsWith("**")); // true
System.out.println(str.startsWith("@@",2)); // ture
System.out.println(str.endsWith("!!")); // true

10. 字符串替换

字符串的替换处理

String str = "helloworld" ;
System.out.println(str.replaceAll("l", "_"));
System.out.println(str.replaceFirst("l", "_"));

11. 字符串的拆分

可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串。

实现字符串的拆分处理

String str = "hello world hello bit" ;
String[] result = str.split(" ") ; // 按照空格拆分
   for(String s: result) {
     System.out.println(s);
}

字符串的部分拆分

String str = "hello world hello bit" ;
String[] result = str.split(" ",2) ;
    for(String s: result) {
      System.out.println(s);
}

12. 字符串截取

从一个完整的字符串之中截取出部分内容。

观察字符串截取

String str = "helloworld" ;
System.out.println(str.substring(5));
System.out.println(str.substring(0, 5));

索引从0开始

13. StringBuffer类

由于String的不可更改特性,为了方便字符串的修改,提供StringBuffer类。

在String中使用"+"来进行字符串连接,但是这个操作在StringBuffer类中需要更改为append()方法:

public synchronized StringBuffer append(各种数据类型 b)

观察StringBuffer使用

public class Test{
public static void main(String[] args) {
    StringBuffer sb = new StringBuffer();
    sb.append("Hello").append("World");
    fun(sb);
    System.out.println(sb);
 }
public static void fun(StringBuffer temp) {
   temp.append("\n").append("www.bit.com.cn");
  }
}

String和StringBuffer最大的区别在于:String的内容无法修改,而StringBuffer的内容可以修改。频繁修改字符串
的情况考虑使用StingBuffer。

注意:

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

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

观察字符串反转:

StringBuffer sb = new StringBuffer("helloworld");
System.out.println(sb.reverse());

 String、StringBuffer、StringBuilder的区别:

  • String的内容不可修改,StringBuffer与StringBuilder的内容可以修改.
  • StringBuffer采用同步处理,属于线程安全操作;而StringBuilder采用异步处理,属于线程不安全操作。
     

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值