前言: 不管你从事任何职业,希望你能尽心尽力
大家好我是 擦擦屁屁闻闻手
,一个有 味道
的公众号,选择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;/加法运算完成后,再次装箱,把基本数值转成对象。 } 复制代码
基本类型直接与 英文的双引号
相连接即可;如:
public class Test { public static void main(String[] args) { int i = 4; String string = i + ""; } } 复制代码
除了 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); } } 复制代码
概述:
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
方法返回该对象的字符串表示,其实该字符串内容就是 对象的类型+@+内存地址值
。 由于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); } } 复制代码
结果:
com.maidao.Student@78308db1 复制代码
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); } } 复制代码
结果:
com.maidao.Student@78308db1 com.maidao.Student@27c170f0 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 复制代码
在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类的API文档中,常用的方法有 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] 复制代码
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 图解:
java.lang.StringBuilder
类
StringBuilder是个字符串的缓冲区,即它是一个容器,容器中可以装很多字符串。并且能够对其中的字符串进行各种操作。它的内部拥有一个数组用来存放字符串内容,进行字符串拼接时,直接在数组中加入新内容。StringBuilder会自动维护数组的扩容。原理如下图所示:(默认16字符空间,超过自动扩充)
图解:
2. 构造方法
根据StringBuilder的API文档,常用构造方法有2个:
public StringBuilder() public StringBuilder(String str)
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()
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
排版