本文主要结构:
final class String类
1.1实例化方式
String类的实例化方式有两类:直接赋值和通过构造方法赋值
String str = "hello";//直接赋值
String str1 = new String("hello world");//通过构造方法赋值
两种实例化方式的比较:
直接赋值:JVM内部维护一个字符串常量池,第一次赋值即入池,当下一次操作进行赋值时,首先判断该值是否在对象池中,若有,直接引用,若无,则开辟新空间存放该值,只开辟一块新空间。
构造方法赋值:每次赋值都会开辟新的空间,因为程序是从右向左执行的,所以在new时开辟的空间很快就会成为垃圾空间,在上述语句执行之后一共会开辟两块空间。
1.2字符串的相等比较
注意:等号“==”与equal( )的使用:
等号操作符比较的是两个变量的值是否相等,对于基本类型来说,比较的是数值大小,对于引用类型来说,比较的是两个对象存放的地址值,而不会比较内容。
在进行字符串内容比较时,可使用String类提供的equals( )方法。
str1.equals(str2);//区分大小写
equalsIngoreCase();//不区分大小写比较
1.3String类的匿名对象
new Test;//String类的匿名对象
"hello".equals(str1);//当两个字符串进行比较时,将字符串常量写在equals之前!!!
1.4字符串常量不可变更
所有字符串都是字符数组,其长度不可更改。在定义字符串常量时,它的内容不可更改。对于以下代码:
public class Ex{
public static void main(String[ ] args){
String str = "hello";
str += " world";
str +=" !!!";
System.out.println(str);
}
}
内存图分析如下(堆中内容无法更改,栈中指向可以更改):
对于字符数组长度不可更改,用俩SB(StringBuffer、StringBuilder)来更改:(俩SB的目的:方便进行字符串的修改)
StringBuffer:
字符串拼接用append( )方法完成:
StringBuffer sb = new StringBuffer();
sb.append("hello").append("world");
System.out.println(sb);
//运行结果:helloworld
String与StringBuffer之间的转换:
String -> StringBuffer
a.通过StringBuffer(String str)的构造方法:public StringBuffer(String str);
b.通过append(String str):StringBuffer
StringBuffer -> String:
调用StringBuffer的toString( )
对于StringBuilder的用法与StringBuffer一致。
注意:解释String、StringBuffer、StringBuilder三者的区别
① String类常量内容不可更改,而俩SB对象可以更改
② StringBuffer使用同步处理、线程安全,性能较低;StringBuilder(推荐使用)使用异步处理、线程不安全、性能较高。当String类对象用“+”进行字符串拼接时,java编译器会自动将String对象变为StringBuilder而后调用append( )方法进行拼接,以便减少空间的浪费。
1.5字符与字符串的相互转化
① char[ ] -> String
public String(char[] value);//将字符数组全部转为字符串
public String(char[] value,int offset,int len);//将字符数组的部分内容转为字符串
② String -> char
public char charAt(int index);//取得字符串指定索引的字符,从0开始
③ String -> char[ ]
public char[] toCharArray();//将字符串转为字符数组
1.6字节数组与字符串的相互转化
① byte[ ] -> String
public String(byte[] value);//将字节数组全部转为字符串
public String(byte[] value,int offset,int len);//将字节数组的部分内容转为字符串
② String -> byte[ ]
public byte[] getBytes();//将字符串转为字符数组
public byte[] getByte(String charSet);//将字符串按照指定编码格式转为字节数组,linux默认的编码为UTF-8,window默认的编码为GBK
1.7字符串的比较方法
//比较相等
String str = "hello";
String str1 = "Hello";
System.out.println(str.equals(str1));// false 区分大小写
System.out.println(str.equalsIgnoreCase(str1));// true 不区分大小写
//比较大小
public int compareTo(String anotherString);//比较两个字符串的大小 返回值为负数、0、正数。按照ASCLL比较,只要发现不一样算出差值返回,不会再进行比较
1.8字符串查找
public boolean contains(Charsequence s);//判断一个字符串是否存在
public int indexOf(String str);//从头开始查找指定字符串的位置,若找到返回位置的开始索引,若无则返回-1
public boolean starsWith(String str);//判断是否以指定字符串开始
public boolean endsWith(String str);//判断是否以指定字符串结尾
1.9字符串替换
public String replaceAll(String regex,String replacement);//将字符串中的所有指定内容替换为新内容
public String replaceFirst(String regex,String replacement);//替换首个内容
1.10字符串拆分
public String[ ] split(String regex);//按照指定格式将字符串全部拆分,若拆不出来,注意用\\转义一下
public String[ ] split(String reget,int limit);//将字符串部分拆分,数组长度为限定的limit长度
1.11字符串截取
public String substring(int beginIndex);//从指定索引开始截取到字符串结尾
public String substring(int beginIndex,int endUndex);//从指定索引开始到指定结束位置[)
1.12其他操作方法
trim();//去掉字符串的两边空格,中间保留
toUpperCase();//将字符串转大写处理
toLowerCase();//将字符串转小写处理
length();//返回字符串长度
isEmpty();//判断是否为空字符串,不包含null
对于 isEmpty( )方法:
public class Ex{
public static void main(String[] args){
String str = null;
String str1 = "";
//System.out.println(str.isEmpty());
//System.out.println(str.length());
System.out.println(str1.isEmpty());
System.out.println(str1.length());
}
}
对于空字符串的String类,程序运行结果为:
对于null的String类,会抛出空指针异常,结果如下:
对于 toUpperCase( )方法:
//首字母大写
public class Ex{
public static void main(String[] args){
System.out.println(firstUpper("yiwesan"));
System.out.println(firstUpper(""));
System.out.println(firstUpper("a"));
}
public static String firstUpper(String str){
if(str.equals("")||str == null){
return str;
}
if(str.length()>1){
return (str.substring(0,1).toUpperCase()+str.substring(1));
}
return (str.toUpperCase());
}
}
运行结果:
Object类:
1.toString( );//取得对象信息
class Person{
private String name;
private int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
}
public class Ex{
public static void main(String[] args){
Person per = new Person("张三",20);
String str = "hello";
fun(per);
fun(str);
}
public static void fun(Object obj){
System.out.println(obj.toString());
}
}
运行结果:
分析:toString( )方法默认调用Object类中的方法,在进行实例化时,应在自定义类中覆写该方法:
public String toString(){
return ("姓名为:"+this.name+",年龄为:"+this.age);
}
运行结果:
2.equals( );//比较两个对象内容
来看以下代码,乍一看输出结果很可能为true,可事与愿违…
class Person{
private String name;
private int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
}
public class Ex{
public static void main(String[] args){
Person per = new Person("张三",20);
Person per1 = new Person("张三",20);
System.out.println(per.equals(per1));
}
}
运行结果:
原因:Object类是所有类的父类,而上面代码的Person类继承了Object类默认的equals( )方法,该方法在Object类中比较的是两个对象的地址!!!
所以,我们要在Person类中进行equals( )方法的覆写:
public boolean equals(Object obj){
//判断地址是否相等
if(obj == this){
return true;
}
//判断传进来的对象不是Person对象
if(!(obj instanceof Person)){
return false;
}
//此时需要比较两个Person对象的内容
//需要向下转型,转回Person对象后比较两者的属性内容
Person per = (Person)obj;
return this.age == per.age && this.name.equals(per.name);
}
此时运行结果为:
3.Objece类可以接收所有引用类型,包括接口与数组
4.Object类是参数的最高统一类型
包装类
包装类就是将基本类型封装到类中
1.数值型包装类(Number的子类):
Byte、Short、Integer(int)、Long、Float、Double
2.对象型包装类(Object的子类):
Boolean、Character(char)
3.装箱与拆箱
装箱:将基本数据类型变为包装类对象,通过每个包装类的构造方法实现装箱处理
拆箱:将包装类中包装的基本数据类型取出,利用包装类提供的xxValue( );例如Integer提供的intValue( );
public class Test{
public static void main(String[] args){
//装箱
Integer integer = new Integer(10);
//拆箱
int data = integer.intValue();
System.out.println(data+10);
}
}
运行结果:
20
4.自动拆装箱(JDK1.5)-语法糖
//自动装箱
Interge integer = 10;
//自动拆箱
System.out.println(integer+10);
使用包装类与使用基本类型在用法上基本一致
注:
①【强制】所有POJO类(类中只有属性与getter/setter,构造方法)使用包装类
②局部变量推荐使用基本类型
5包装类进行数值比较使用equals方法
6对于Interger var = ? 直接赋值在[-128,127]区间内赋值,Integer对象在缓存池产生,会复用已有对象,在这个区间外的所有数据均在堆上产生,并且不会复用已有对象。
public class Ex{
public static void main(String[] args){
Integer i1 = new Integer(10);
Integer i2 = new Integer(10);
System.out.println(i1 == i2);
}//运行结果:false
public static void main(String[] args){
Integer i1 = 10;
Integer i2 = 10;
System.out.println(i1 == i2);
}//运行结果:true
public static void main(String[] args){
Integer i1 = 130;
Integer i2 = 130;
System.out.println(i1 == i2);
}//运行结果:false
}
7.String类与基本类型的相互转换
① String -> 基本类型
使用各个包装类提供的parseXX( ),Integer.parseInt(str)//把字符串转换为整型
public class Ex{
public static void main(String[] args){
//当字符串中包含了非数字,在运行时会抛出NumberFormatException
String str = "123";
int i = Integer.parseInt(str);
System.out.println(i+10);
}
}
输出结果:
133
注:
当字符串中包含了非数字,在运行时会抛出NumberFormatException
当String -> 基本类型时,要先判断一下是否为数字组成~
② 基本类型 -> String
a."+"
b.通过String的构造方法
c.推荐:使用String.valueOf(所有基本类型)
System.out.println(String.valueOf(123)+10);//输出结果:12310
若有错误、纰漏,还请指正,共同学习进步!!