Java中常用的类和API
前言:不管你从事任何职业,希望你能尽心尽力
大家好我是擦擦屁屁闻闻手
,一个有味道
的公众号,选择IT就得做好一直学习的心态,毕竟互联网技术更新迭代很快,不学习就要落后于人啦,今天我们来学习一下Java中常用的类和API
包装类
-
概述:
Java为我们提供了两个类型系统,基本数据类型
与引用数据类型
,使用基本类型在于效率,然而很多情况,会创建对象使用,因为对象可以做更多的事情,如果想要我们的基本数据类型像对象一样的操作,就可以使用基本数据类型对应的包装类
,如下:
基本类型 | 对应的包装类(位于java.lang包中) |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
除
char
类型外,其余基本数据类型的包装类都是该基本数据类型首字母大写
- 装箱与拆箱
基本数据类型与包装类对象
之间的来回装换的过程称为“装箱”和“拆箱”
-
装箱:
从基本数据类型转换为包装类对象 -
拆箱:
从包装类对象想转换为基本数据类型
举例:(用Integer于int为例)
- 基本数据类型->包装类对象
public class Test {
public static void main(String[] args) {
int number = 4;
Integer integer = new Integer(number);
Integer integer1 = Integer.valueOf(number);
}
}
- 包装类对象->基本数据类型
public class Test {
public static void main(String[] args) {
Integer number = 4;
int value = number.intValue();
}
}
- 自动装箱与自动拆箱
由于我们经常要做基本数据类型与包装类之间的转换,从java5(Jdk1.5)开始,基本数据类型与包装类的装箱、拆箱动作可以直接完成:
public class Test {
public static void main(String[] args) {
Integer i = 4;//自动装箱。相当于Integer i = Integer.valueOf(4);
i = i + 5;//等号右边:将i对象转成基本数值(自动拆箱) i.intValue() + 5;/加法运算完成后,再次装箱,把基本数值转成对象。
}
- 基本数据类型与字符串之间的转化
- 基本数据类型转换为String(昨天我们说用String构造方法转换,今天我们来最简单的一种)
基本类型直接与
英文的双引号
相连接即可;如:
public class Test {
public static void main(String[] args) {
int i = 4;
String string = i + "";
}
}
- String转换为对应的基本数据类型
除了
Character
类之外,其他所有包装类都具有parseXxx静态方法可以将字符串参数转换为对应的基本类型:
包装类 | 方法 | 参数 | 返回值 | 描述 |
---|---|---|---|---|
Byte | static parseByte() | Sting s | byte | 将字符串参数转换为对应的byte基本类型 |
Short | static parseShort() | Sting s | short | 将字符串参数转换为对应的short基本类型 |
Integer | static parseInt() | Sting s | int | 将字符串参数转换为对应的int基本类型 |
Long | static parseLong() | Sting s | long | 将字符串参数转换为对应的long基本类型 |
Float | static parseFloat() | Sting s | float | 将字符串参数转换为对应的float基本类型 |
Double | static parseDouble() | Sting s | double | 将字符串参数转换为对应的double基本类型 |
Boolean | static parseBoolean() | Sting s | boolean | 将字符串参数转换为对应的boolean基本类型 |
案例:
(仅以Integer类的静态方法parseXxx为例
public class Test {
public static void main(String[] args) {
String string = "100";
int parseInt = Integer.parseInt(string);
}
}
Object类
-
概述:
java.lang.Object类是Java语言中的根类,它是所有类的父类,它中描述的所有方子类都可以使用,在对象实例化的时候,最终陪你过找的父类就是Object
如果一个类没有指定特定的父类,那么默认则继承自Object类,例如:
public class MyClass /*extends Object*/ {
// ...
}
根绝JDK源代码以及Object类的API文档,Object类中的包含的方法有11个,今天我我们主要学习其中的2个:
-
public String toString()
:返回该对象的字符串表示。 -
public boolean equals(Object obj)
:指示其他某个对象是否与此对象“相等”。
-
toString
方法
-
public String toString()
:返回该对象的字符串表示。
toString
方法返回该对象的字符串表示,其实该字符串内容就是对象的类型aaa@qq.com+内存地址值
。
由于toString方法返回的结果是内存地址
,而在开发中,经常需要按照对象的属性得到相应的字符串表现形式,因此也需要重写它。案例:
- 先创建一个
student
类,未重写toString方法
public class Student extends Person {
private String name ;
private Integer age;
public Student() {
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
public class Test {
public static void main(String[] args) {
Student student = new Student("张三", 20);
System.out.println(student);
}
}
结果:
aaa@qq.com
1.1 接下来我们覆盖重写一下toString方法(mac版idea command+n
)呼出下拉框
@Override //重写
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
结果:
Student{name='张三', age=20}
小贴士:在我们直接使用输出语句输出对象名的时候,其实通过该对象调用了
其toString()
方法
-
equals
方法
public boolean equals(Object obj):
指示其他某个对象是否与此对象“相等”。
调用成员方法equals
并指定参数为另一个对象,则可以判断这两个对象
是否是相同的。这里的“相同”有默认和自定义两种方式。
2.1 默认地址比较:
如果没有覆盖重写equals方法,那么Object类中默认进行== 运算符的对象地址比较,只要不是同一个对象,结果必然为false。
注意凡是用
new
关键字创建的对象都是在堆里,下图可以看出虽然我们创建的两个对象尽管传入的参数的是一样的,但是在内存中指向的地址值却是不一样的
代码实现:
public class Test {
public static void main(String[] args) {
Student student = new Student("张三", 20);
Student student1 = new Student("张三", 20);
System.out.println(student);
System.out.println(student1);
System.out.println(student==student1);
}
}
结果:
aaa@qq.com
aaa@qq.com
false
由此可以看出没有覆盖重写equals方法,那么Object类中默认进行==运算符的对象地址比较
2.2 对象内容比较:
如果希望进行对象的内容比较,即所有或指定的部分成员变量相同就判定两个对象相同,则可以覆盖重写equals方法
@Override
public boolean equals(Object o) {
//如果两个对象的地址值相同那么就是同一个对象
if (this == o) return true;
//如果对象为null 或者是类型信息不同 则认为不同
if (o == null || getClass() != o.getClass()) return false;
//转换当前类型
Student student = (Student) o;
//判断必须 两个属性全部相等才是同一个
return Objects.equals(name, student.name) &&
Objects.equals(age, student.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
用代码解释:if (this == o) return true;
Student student = new Student("张三", 20);
Student student1 = student;
我们将student赋值给student1,就相当于将student在内存中的地址值赋值给student1,所以此时对象student和student1指向的都是同一个地址值,那必然是相等的
图解:
补充:我们刚重写equals方法时还看到了
hashCode
方法,那么这个hashCode
到底是个啥
配合下边代码重复阅读: 在一个Java应用的执行期间
如果一个对象提供给equals做比较的信息没有被修改的话
,该对象多次
调用hashCode()方法,该方法必须始终如一返回同一个integer
。如果两个对象根据equals(Object)方法是相等的,那么调用二者各自的hashCode()方法必须产生同一个integer
结果。并不要求 根据equals(java.lang.Object)方法不相等的两个对象,调用二者各自的hashCode()方法必须产生不同的integer结果。
最后这句话是不是很拗口我们用代码解释一下
public class Test {
public static void main(String[] args) {
String string = "通话";
String string1 = "重地";
// 根据equals(java.lang.Object)方法不相等的两个对象
System.out.println("两个对象的equals比较:"+(string == string1));
//调用二者各自的hashCode()方法必须产生不同的integer结果。
System.out.println("string对象hashCode:"+string.hashCode());
System.out.println("string1对象的hashCode:"+string1.hashCode());
System.out.println("两个对象的hashCode比较:"+(string.hashCode() == string1.hashCode()));
}
}
结果:
两个对象的equals比较:false
string对象hashCode:1179395
string1对象的hashCode:1179395
两个对象的hashCode比较:true
- 在刚才IDEA自动重写equals代码中,使用到了java.util.Objects 类,那么这个类是什么呢?
在JDK7添加了一个
Objects
工具类,它提供了一些方法来操作对象
,它由一些静态的实用方法
组成,这些方法是null-save(空指针安全的
)或null-tolerant(容忍空指针的)
,用于计算对象的hashcode、返回对象的字符串表示形式、比较两个对象。
在比较两个对象的时候,Object的equals方法容易抛出空指针异常,而Objects类中的equals方法就优化了这个问题。方法如下:
public static boolean equals(Object a, Object b) :判断两个对象是否相等。
源码:
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
Java中有很多类帮我们实现过equals方法,比如
String、Integer等
System类
-
概述:
获取与系统相关
的信息或系统级操作,类中提供了大量的静态方法,在System类的API文档中,常用的方法有
- public static long currentTimeMillis():返回以毫秒为单位的当前时间。
- public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length):将数组中指定的数据拷贝到另一个数组中。
currentTimeMillis方法:
实际上,currentTimeMillis方法就是 获取 当前系统时间 与1970年01月01日00:00点之间的毫秒差值
import java.util.Date;
public class SystemDemo {
public static void main(String[] args) {
//获取当前时间毫秒值
System.out.println(System.currentTimeMillis()); // 1516090531144
}
}
arraycopy方法
数组的拷贝动作是系统级的,性能很高。System.arraycopy方法具有5个参数,含义分别为:
参数序号 | 参数名称 | 参数类型 | 参数含义 |
---|---|---|---|
1 | src | Obgect | 源数组 |
2 | srcPos | int | 源数组索引起始位置 |
3 | dest | Obgect | 目标数组 |
4 | destPos | int | 目标数组索引起始位置 |
5 | length | int | 复制元素个数 |
public class Test {
public static void main(String[] args) {
int[] src = new int[]{1, 2, 3, 4, 5};
int[] dest = new int[]{6, 7, 8, 9, 10};
System.arraycopy(src, 0, dest, 0, 3);
System.out.println(Arrays.toString(dest));
}
}
源数组:[1, 2, 3, 4, 5]
arraycopy后的目标数组:[1, 2, 3, 9, 10]
StringBuilder类
- 字符串拼接问题:
- 由于String类的对象内容不可改变,所以每当进行字符串拼接时,总是会在内存中创建一个新的对象。例如:
public class Test {
public static void main(String[] args) {
String s = "Hello";
s += "World";
System.out.println(s);
}
}
在API中对String类有这样的描述:
字符串是
常量
,它们的值在创建后不能被更改
根据这句话分析我们的代码,其实总共产生了三个字符串,即"Hello" 、"World" 和"HelloWorld"
,引用变量s首先指向Hello对象,最终指向拼接出来的新字符串对象,即HelloWord图解:
由此可知,如果对字符串进行拼接操作,每次拼接,都会构建一个新的String对象,既耗时,又浪费空间。为了解决这一问题,可以使用java.lang.StringBuilder
类
StringBuilder是个字符串的缓冲区,即它是一个容器,容器中可以装很多字符串。并且能够对其中的字符串进行各种操作。它的内部拥有一个数组用来存放字符串内容,进行字符串拼接时,直接在数组中加入新内容。StringBuilder会自动维护数组的扩容。原理如下图所示:(默认16字符空间,超过自动扩充)
图解:
2. 构造方法
根据StringBuilder的API文档,常用构造方法有2个:
-
public StringBuilder()
:构造一个空的StringBuilder容器。 -
public StringBuilder(String str)
:构造一个StringBuilder容器,并将字符串添加进去。
public class Test {
public static void main(String[] args) {
StringBuilder sb1 = new StringBuilder();
System.out.println(sb1); // (空白)
// 使用带参构造
StringBuilder sb2 = new StringBuilder("Hello");
System.out.println(sb2);
}
}
Hello
- 常用方法
StringBuilder常用的方法有2个:
-
public StringBuilder append(...)
:添加任意类型数据的字符串形式,并返回当前对象自身。 -
public String toString()
:将当前StringBuilder对象转换为String对象。
append方法
append方法具有多种重载
形式,可以接收任意类型
的参数。任何数据作为参数都会将对应的字符串内容
添加到StringBuilder中。例如:
public class Test {
public static void main(String[] args) {
//创建对象
StringBuilder builder = new StringBuilder();
//public StringBuilder append(任意类型)
StringBuilder builder2 = builder.append("hello");
//对比一下
System.out.println("builder:" + builder);
System.out.println("builder2:" + builder2);
System.out.println(builder == builder2); //true
// 可以添加 任何类型
builder.append("hello");
builder.append("world");
builder.append(true);
builder.append(100);
// 在我们开发中,会遇到调用一个方法后,返回一个对象的情况。然后使用返回的对象继续调用方法。
// 这种时候,我们就可以把代码现在一起,如append方法一样,代码如下
//链式编程
builder.append("hello").append("world").append(true).append(100);
System.out.println("builder:" + builder);
}
}
builder:hello
builder2:hello
true
builder:hellohelloworldtrue100helloworldtrue100
备注:StringBuilder已经覆盖重写了Object当中的toString方法。
toString方法
通过toString方法,StringBuilder对象将会转换为不可变的String对象。如:
public class Test {
public static void main(String[] args) {
// 链式创建
StringBuilder sb = new StringBuilder("Hello").append("World").append("Java");
// 调用方法
String str = sb.toString();
System.out.println(str); // HelloWorldJava
}
}
HelloWorldJava
今天就先写到这里,(明天休息一天停更,周末还是要陪陪对象
的),如有写的不对的地方,请大家指正,祝大家周末愉快,下周再见
本文使用mdnice
排版
上一篇: python代码直接生成可执行exe文件
下一篇: 就是要让你搞懂Nginx,这篇就够了!