String类(上)
1.String类的两种实例化方式
1.1.直接赋值(常用)
String str = "Hello Bit";//str是一个对象,那么“Hello Bit”就应该保存在堆内存中
System.out.println(str);
1.2.传统方法:String本身是一个类,既然是类,就存在构造方法,String类其中一种构造方法如下
public String(String str);//带参构造
//使用new关键字进行对象实例化
String str = new String("Hello Bit");
System.out.println(str);
2.字符串相等比较
2.1.用“==”比较
2.1.1.基本数据类型比较
int x = 10;
int y = 10;
System.out.println(x==y);//true
2.1.2.String类对象上使用“==”
String str1 = "Hello";
String str2 = new String("Hello");
System.out.println(str1 == str2);//false
分析:两个字符串内容相同,而使用“==”得到的结果却是错误,为什么呢?内存分析图如下
“==”本身是进行数值比较,那么比较的是两个对象所保存内容地址的比较,并没有比较对象的内容,想要比较内容应该使用String类的equals方法。
>>>请解释String类“==”和equals的区别:
3.字符串常量是String类的匿名对象
在任何语言的底层,都不会提供直接的字符串类型,现在所谓的字符串只不过是高级语言提供给开发者方便开发的支持而已。在Java中,本身也没有直接提供字符串常量的概念,所以使用“”定义的内容本质上来讲都是String的匿名对象。
所以“String str = "Hello"”本质上就是将一个匿名的String类对象设置有名字,而且匿名对象一定保存在堆内存。
注:在开发中,如果要判断用户输入的字符是否等同于特定字符串,尽量将特定字符串放在前面(方法二),防止输入为空,出现空指针(NullPointException)问题,如下:
String str = null;//假设由用户输入
System.out.println(str.equals("Hello"));//方法1
System.out.println("Hello".equals(str));//方法2
另外如上也说明"Hello"字符串常量是匿名对象,因为equals是对象方法。
4. 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
为什么现在没有开辟新的堆内存空间?
因为String类的设计使用了共享模式:在JVM底层实际上会自动维护一个对象池(字符串对象),如果现在采用了直接赋值的模式进行String类的对象实例化操作,那么该实例化对象(字符串内容)将自动保存到这个对象池中。如果下次继续使用直接赋值的模式声明String类对象,此时对象池之中如若有指定内容,将直接进行引用;如果没有,则开辟新的字符串对象而后将其保存在对象池之中以供下次使用。(所谓的对象池就是一个对象数组,目的是减少开销)
4.2.构造方法(标准方法)
String str = new String("Hello");
使用String构造方法就会开辟两块堆内存空间,并且其中一块堆内存将成为将成为垃圾空间,除此之外,也会对字符串共享产生影响:该字符串常量并没有保存在对象池之中
String str1 = new String("hello");
String str2 = "hello";
System.out.println(str1 == str2);//false
解决办法:public String intern();//String类提供方法入池
String str1 = new String("hello").intern();
String str2 = "hello";
System.out.println(str1 == str2);//true
>>>请解释String类中两种实例化对象方法的区别:
综上,虽然构造方法是实例化对象的标准方法,但是一般会采用第一种方式即直接赋值。
5.字符串常量不可变更:字符串常量一旦定义不可变更
所有语言对于字符串底层的实现都是字符数组,数组的最大缺陷就是长度固定,在定义字符串常量时,它的内容不可变更,如下:
String str = "hello";
str = str + "world";
str += "!!!";
System.out.println(str);//hello world!!!
以上字符串的变更是字符串对象的变更而非字符串常量,字符串对象的引用一直在改变,而且会形成大量的垃圾空间,因为这个特点,如下代码不该出现在开发中:
String str = "hello";
for(int i = 0; i < 100; i++){
str += i;
}
Ststem.out.println(str);
//当很多用户都使用如上操作,那么产生的垃圾空间将相当可观
原则:字符串使用就采用直接赋值
字符串比较就使用equals()实现
字符串别改变太多(防止产生大量垃圾空间)
6.字符与字符串:字符串就是一个字符数组,所以在String类里面支持有字符数组转换为字符串以及字符串变为字符的操作方法。
No. | 方法名称 | 类型 | 描述 |
1 | public String(char value[]) | 构造 | 将字符数组中的所有内容变为字符串 |
2 | public String(char value[],int offset,int count) | 构造 | 将部分字符数组中的内容变为字符串 |
3 | public char charAt(int index) | 普通 | 取得指定索引位置的字符(索引从0开始) |
4 | public char[] toChaArray() | 普通 | 将字符串变为字符返回 |
6.1.charAt()方法
//charAt()方法
String str = "hello";
System.out.println(str.charAt(0));//h
System.out.println(syr.charAt(10));//索引超出字符串长度:StringIndexOutOfBoundsException
6.2.字符串与字符数组的转换
String str = "helloworld";
//字符串变为字符数组
char[] data = str.toCharArray();
for(int i = 0; i < data.length; i++){
data[i] -= 32;//小写转大写
System.out.println(data[i] + "、");
}
//字符数组变为字符串
System.out.println(new String(data));//全部转换
System.out.println(new String(data,5,5));//部分转换
>>>判断一个字符串是否由数字组成
7.字节与字符串
字节常用于数据传输以及编码转换处理中,在String中提供有对字节的支持
No. | 方法名称 | 类型 | 描述 |
1 | public String(byte bytes[]) | 构造 | 将字节数组变为字符串 |
2 | public String(byte bytes[],int offset,int length) | 构造 | 将部分字节数组中的内容变为字符串 |
3 | public byte[] getBytes() | 普通 | 将字符串以字节数组的形式返回 |
4 | public byte[] getBytes(String charsetName)throws UnsupportedEncodingException | 普通 | 编码转换处理 |
字符串与字节数组的转换处理
String str = "helloworld";
byte[] data = str.getBytes();
for(int i = 0; i < data.length; i++){
data[i] -= 32;//转大写的字节数组
System.out.println(data[i] + "、");
}
System.out.println(new String(data));
通过程序可以发现,字节并不适合处理中文,只有字符适合处理中文,按照程序的概念来讲,一个字符等于两个字节,字节只适合处理二进制数据。
8.字符串比较
前面使用String类提供的equals()方法,该方法本身是可以进行区分大小写的相等判断,除了这个方法,String类还提供如下比较操作:
No. | 方法名称 | 类型 | 描述 |
1 | public boolean equals(Object anObject) | 普通 | 区分大小写的比较 |
2 | public boolean equalsIanoreCase(String anotherString) | 普通 | 不区分大小写的比较 |
3 | public int compareTo(String anotherString) | 普通 | 比较两个字符串大小关系 |
不区分大小写比较:
//不区分大小写的比较
String str1 = "hello";
String str2 = "Hello";
System.out.println(str1.equals(str2));//false
System.out.println(str1.equalsIgnoreCase(str2));//true
在String类中compareTo()方法是一个非常重要的方法,它区分大小写,该方法返回一个类型,该数据会根据大小关系返回三类内容:
相等,返回0
小于,返回内容小于0
大于,返回内容大于0
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("杨"));