- String类
- String类的实例化:
- String str = “hello”;
- String str = new String(“hello”);
- String类 == 和 equals 的区别:
1."==" :进行的数值比较,在基本数据类型中比较的是数值的大小,在String类中比较的是两个字符串对象的内存地址数值。
2.“equals()”:可以进行字符串内容的比较。
- 在String类的直接赋值方法中,定义的内容本质上就是String的匿名对象,匿名对象一定保存在堆内存中。
任何的字符串常量都是String的匿名对象,该对象永远不能为null。
- 手动入池:利用String类中提供的方法:public String intern();
入池操作:String str = new String(“hello”).intern();
- 字符串的比较
String str = “hellobit”; //存放在常量池
String str2 = new String(“hellobit”); //存放在堆内存
String str3 = “hellobit”;//存放在常量池
String str4 = “hello”+“bit”;//str4 = “hellobit” //常量与常量拼接,在编译期就确定为hellobit了,保存在常量池
String str5 = “hello”;
String str6 = str5+“bit”;//str5是一个变量 //str != str6 因为内存地址数值不同
String str7 = “hello”+new String(“bit”); //str != str7 因为内存地址数值不同
String str8 = new String(“hello”) +new String(“bit”); //str != str8 因为内存地址数值不同
String str9 = new String(“terry”).intern();
String str10 = “terry”; //str9 == str10 都保存的是常量池的地址
String str11 = new String("" + “hellobit”).intern(); //str == str11 内存地址数值相同
在比较两个字符串时:把握住 "=="比较的是字符串对象的内存地址数值,只有字符串常量保存在常量池中时,两个字符串对象的内存地址数值才相同,只要使用关键字new进行对象实例化,那必然在堆内存开辟了空间,存放在了堆内存上,内存地址数值必然不同。
- 字符串不可变更
String str = “hello”;
str = str + “world”;
在这段代码中,虽然输出的结果是 “helloworld”,但是字符串常量没有变更,变更的是字符串对象,即str所保存的内存地址数值发生了变化。如果字符串对象的引用改变的太多,会形成大量的垃圾空间。
- 字符与字符串
String、StringBuffer、StringBuilder的区别和联系:
- StringBuffer中有线程安全的关键字synchornized,采用同步处理,在多线程情况下使用,而String、StringBuilder没有关键字,采用异步处理,单线程,不安全。
- 在字符串拼接上,String每次都会产生新的空间,而StringBuffer和StringBuilder的append()方法不会产生垃圾空间。
- 在进行拼接时,优先选择StringBuilder(),因为String的拼接底层被优化为StringBuilder,并用StringBuilder.append()进行拼接,输出结果调用StringBuilder.toString()方法,返回值为String。
- String的内容不可修改,StringBuffer和StringBuilder的内容可以修改。
- String和StringBuffer类不能直接转换,如果想要互相转换,可以采用如下原则:
● String变为StringBuffer:利用StringBuffer的构造方法或append()方法;
● StringBuffer变为String:调用toString()方法。
- 字符串比较的方法:
1.equals():区分大小写的比较
2.equalsIgnoreCase():不区分大小写的比较
3.compareTo:比较字符串大小关系
- compareTo()方法的返回值:
要想了解返回值是什么,首先需要了解compareTo()方法的源码,从源码中可以知道各种情况时,返回值是什么。
从源码中我们可以看到,将两个字符串变为字符数组,然后相同下标的字符进行比较,如果不相等,则返回两个字符的差值,如果最小字符数组的长度已经比较完了,则返回两个字符数组长度之差。
//两个字符串长度相等时,返回值为字符的差值即对应ASCII码表的差值
public class Test {
public static void main(String[] args) {
String str = "hellobit";
String str2 = "hellobat";
System.out.println(str.compareTo(str2));
}
}
运行结果:
//两个字符串长度不等时,返回值为字符串长度
public class Test {
public static void main(String[] args) {
String str = "hellobit";
String str2 = "hellobitt";
System.out.println(str.compareTo(str2));
}
}
运行结果:
- 字符串的常用操作方法:
1.charAt():取得指定索引位置的字符,索引从零开始
2.toCharArray():将字符串变为字符数组返回
3.Character.isDigit():判断一个字符是否为数字
4.contains():判断一个字符串是否存在
5.replaceAll():替换所有的指定内容
6.replaceFirst():替换首个内容
7.split():将字符串全部/部分拆分,也别注意* ^ . \ : |这六种符号,:可不加反斜杠,其它注意要加\。
8.substring():截取内容
9.trim():去掉字符串中的左右空格,保留中间空格
10.concat():字符串连接,等同于"+",不入池
更多具体的方法可下载jdk-9或者其他版本查看。
- Object类
- Object是java默认提供的一个类,是所有类的父类,所有类的对象都可以使用Object进行接受。
class Person{}
class Student{}
public class Test {
public static void fun(Object object) {
System.out.println(object);
}
public static void main(String[] args) {
fun(new Person());
fun(new Student());
}
}
运行结果:
上图的运行结果是Person类和Student类的实例化对象的哈希值,之所以会输出这种结果,是因为默认调用了Object的toString()方法;
在使用对象直接输出时,默认输出的是一个地址编码,如果是String类,该类对象直接输出的是内容:
class Person{}
public class Test {
public static void fun(Object object) {
System.out.println(object);
}
public static void main(String[] args) {
fun(new Person());
fun("hello");
}
}
运行结果:
如果觉得默认给出的toString()方法功能不足,就在需要的子类上覆写toString()方法。
class Person{
private String name;
private int age;
public Person(String name,int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "姓名:"+this.name+",年龄:"+this.age;
}
}
public class Test {
public static void fun(Object object) {
System.out.println(object.toString());
}
public static void main(String[] args) {
fun(new Person("张三",20));
}
}
- 接受引用数据类型
前面Object可以接受任意的对象,但是Object并不局限于此,它可以接收所有数据类型,包括:类、数组、接口。
//接受数组对象
public class Test {
public static void main(String[] args) {
Object object = new int[]{1,2,3,4,5};
//向下转型,需要强转
int[] data = (int[]) object;
for (int i:data) {
System.out.println(i);
}
}
}
//接受接口
interface IMessgae {
void getMessage();
}
class Message implements IMessgae {
@Override
public String toString() {
return "北京欢迎你";
}
@Override
public void getMessage() {
System.out.println("为你感到天地");
}
}
public class Test {
public static void main(String[] args) {
IMessgae iMessgae = new Message(); //子类向父接口转型
Object object = iMessgae; //接口向Object转型
System.out.println(object);
IMessgae ims = (IMessgae) object; 向下转型,强转
ims.getMessage();
}
}
- 包装类
- 包装类就是将基本数据类型封装到类中
基本数据类型 | 包装类 |
---|---|
byte | Byte |
boolean | Boolean |
short | Short |
char | Character |
int | Integer |
long | Long |
float | Float |
double | Double |
- 自定义一个包装类
class DoubleDemo {
private double num;
public DoubleDemo(double num) {
this.num = num;
}
public double doubleValue() {
return this.num;
}
}
结论:将基本数据类型包装为一个类对象的本质就是利用Object进行处理。
3.包装类分为两种类型:
对象型(Object的直接子类):Boolean、Character(char)
数值型(Number的直接子类):Byte、Double、Short、Long、Interger、Float;
- 装箱与拆箱
● 装箱:将基本数据类型变为包装类对象,利用每一个包装类提供的构造方法实现装箱处理。
● 拆箱:将包装类中包装的基本数据类型取出。利用Number类中提供的六种方法。
装箱分为:显示装箱、自动装箱
1)显示装箱(调用构造方法): Integer num = new Integer(55);
2)自动装箱(调用valueOf()方法):Integer x = 55;
拆箱分为:显示拆箱、自动拆箱
1)显示拆箱:int data = num.intValue();
2)自动拆箱(调用intvalue、doublevalue等方法):int i = x;
- 包装类对象之间的数值比较
public class Test {
public static void main(String[] args) {
Integer num1 = new Integer(10);
Integer num2 = new Integer(10);
System.out.println(num1 == num2);
System.out.println(num1 == new Integer(10));
System.out.println(num1.equals(new Integer(10)));
}
}
运行结果:
在包装类对象之间值的比较中,"=="比较的是对象所存的内存地址数值,"equals"方法比较的是包装类对象的值。
- Integer对象的赋值范围
public class Test {
public static void main(String[] args) {
Integer num1 = 100;
Integer num2 = 100;
System.out.println(num1 == num2);
Integer num3 = 300;
Integer num4 = 300;
System.out.println(num3 == num4);
}
}
运行结果:
在 -128 至 127范围内的赋值,Integer对象是在IntegerCache.cache产生,会复用已有对象,这个区间内的Integer值可以直接使用"=="进行判断,但是这个区间外的所有数据,都会在堆上产生,并不会复用已有对象,推荐使用equals方法进行判断。
Integer中valueOf方法的源码
关于基本数据类型与包装数据类型的使用标准:
1)【强制】所有的POJO类属性必须使用包装数据类型。
2)【强制】RPC方法的返回值和参数必须使用包装数据类型。
3)【推荐】所有的局部变量使用基本数据类型。
- 字符串与基本数据类型转换
- String变为int类型(Integer类):public static int parseInt(String s) throws NumberFormatException
- String变为double类型(Double类):public static double parseDouble(String s) throws NumberFormatException
3.String变为boolean类型(Boolean类):public static boolean parseBoolean(String s)
public class Test {
public static void main(String[] args) {
String str = "123";
int num = Integer.parseInt(str);
System.out.println(num);
String str4 = "123adf";
int num4 = Integer.parseInt(str4);
System.out.println(num4);
String str2 = "123.123";
double num2 = Double.parseDouble(str2);
System.out.println(num2);
String str5 = "123asd.123sad";
double num5 = Double.parseDouble(str5);
System.out.println(num5);
String str3 = "truesds";
boolean num3 = Boolean.parseBoolean(str3);
System.out.println(num3);
String str6 = "true";
boolean num6 = Boolean.parseBoolean(str6);
System.out.println(num6);
}
}
运行结果:
在上述代码运行时,出现了异常,查看异常来源可知,当字符串转为数字时,字符串的组成有非数字,那么转换就会出现错误(NumberFormatException),当出现这个异常时,我们就需要写一堆程序即try…catch、try…finally、try…catch…finally去对异常进行处理。
在上述代码中,还值得注意的一点是,只有当字符串为true时,boolean类型输出的才是true,其他都是false。
- 基本数据类型变为字符串
1.任何数据类型使用了"+"连接空白字符串就变为了字符串类型。
2.使用String类中提供的valueOf()方法,此方法不产生垃圾。
public class Test {
public static void main(String[] args) throws NumberFormatException {
String str = String.valueOf(100);
String str2 = String.valueOf(10.1f);
String str3 = String.valueOf(10.10);
String str4 = String.valueOf(false);
String str5 = String.valueOf(12L);
String str6 = String.valueOf('a');
System.out.println(str);
System.out.println(str2);
System.out.println(str3);
System.out.println(str4);
System.out.println(str5);
System.out.println(str6);
}
}
运行结果: