05常用类

常用类

Object类

Object类位于java.lang包中,java.lang包包含着Java最基础和核心的类,在编译时会自动导入;

Object类是所有Java类的根基类,如果在类的声明中未使用extends关键字指明其基类,则默认基类为Object类。

public class Person{
   
    
}
public class Person extends Object{
   

}

在Object类中提供了一些常用的方法

toString方法

Object类中定义有public String toString()方法,其返回值是 String 类型,描述当前对象的有关信息。

在进行String与其它类型数据的连接操作时(如:System.out.println(“info”+person)),将自动调用该对象类的 toString()方法。

可以根据需要在用户自定义类型中重写toString()方法。

equals方法

Object类中定义有: public boolean equals(Object obj) 方法提供定义对象是否 “相等” 的逻
辑。

Object 的 equals 方法 定义为: x.equals (y) 当 x 和 y是同一个对象的应用时返回 true 否则返
回 false

JDK提供的一些类,如String,Date等,重写了Object的equals方法,调用这些类的equals方法,x.equals (y) ,当x和y所引用的对象是同一类对象且属性内容相等时(并不一定是相同对象),返回 true 否则返回 false。

可以根据需要在用户自定义类型中重写equals方法。

hashCode方法

在Java的Object类中还有一个方法 public native int hashCode(); 该方法返回一个int类型的数值,并且是本地方法。hashcode本身代表对象的地址,说的是对象在hash表中的位置,物理地址说的对象存放在内存中的地址,java中通过对象的内部地址(也就是物理地址)转换成一个整数,然后该整数通过hash函数的算法就得到了hashcode,这基本来说就是对象的唯一标识了。既然是唯一标识它主要是为了查找以及比较的快捷性

对于包含容器类型的程序设计语言来说,基本上都会涉及到hashCode。在Java中也一样,hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,这样的散列集合包括HashSet、HashMap以及HashTable。

当向集合中插入对象时,如何判别在集合中是否已经存在该对象了?(该集合中不允许重复的元素存在)

如果直接调用equals方法来逐个进行比较,这个方法确实可行。但是如果集合中已经存在一万条数据或者更多的数据,如果采用equals方法去逐一比较,效率必然是一个问题。此时hashCode方法的作用就体现出来了,当集合要添加新的对象时,先调用这个对象的hashCode方法,得到对应的hashcode值,实际上在HashMap的具体实现中会用一个table保存已经存进去的对象的hashcode值,如果table中没有该hashcode值,它就可以直接存进去,不用再进行任何比较了;如果存在该hashcode值, 就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址,所以这里存在一个冲突解决的问题,这样一来实际调用equals方法的次数就大大降低了,从而提高了效率。

我们会重写hashCode方法,使其和对象的属性值相关,不同对象,相同的属性得到的hash值相同; 并且不同对象,不同的属性也可能得到相同的hash值。反之,不同的hash值,一定是不同的对象,不同的属性。

clone方法

java赋值是复制对象引用,如果我们想要得到一个对象的副本,使用赋值操作是无法达到目的的。

Student s1=new Student();
s1.setAge(17);
s1.setName("Tom");
Student s2=s1;
System.out.println(s1==s2);//true

此时只存在一个Student对象!!!

如果创建一个对象的新的副本,也就是说他们的初始状态完全一样,但以后可以改变各自的状态,而互不影响,就需要用到java中对象的复制,如原生的 clone() 方法。

Object对象有个clone()方法,实现了对象中各个属性的复制,但它的可见范围是protected的,所以实体类使用克隆的前提是:实现Cloneable接口,这是一个标记接口,自身没有方法;覆盖clone()方法,可见性提升为public。

如果不实现这个接口,则会抛出CloneNotSupportedException(克隆不被支持)异常。

Student.java实体类

package com.uek.pojo;

import java.util.Objects;

/**
 * @version 0.0.1
 * @auther ycb
 */
public class Student implements Cloneable{
   
    private int age;
    private String name;

    @Override
    public Object clone() throws CloneNotSupportedException {
   
        return super.clone();
    }

    @Override
    public boolean equals(Object o) {
   
        if (this == o) return true;
        if (!(o instanceof Student)) return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
   
        return Objects.hash(age, name);
    }
}

测试

package com.uek.obj;

public class CloneTest {
   
    public static void main(String[] args) throws CloneNotSupportedException {
   
        Student s1 = new Student(17, "Tom");// 通过clone方法来复制对象
        Student s2 = (Student) s1.clone();
        System.out.println(s1==s2);
        System.out.println(s1.equals(s2));
        System.out.println(s1);
        System.out.println(s2);
    }
}

浅拷贝和深拷贝

浅拷贝:被复制对象的所有值属性都含有与原来对象的相同,而所有的对象引用属性仍然指向原来的对象。

深拷贝:在浅拷贝的基础上,所有引用其他对象的变量也进行了clone,并指向被复制过的新对象。

也就是说,一个默认的clone()方法实现机制,仍然是赋值。如果一个被复制的属性都是基本类型,那么只需要实现当前类的cloneable机制就可以了,此为浅拷贝。

如果被复制对象的属性包含其他实体类对象引用,那么这些实体类对象都需要实现cloneable接口并覆盖clone()方法。

包装类

概述

JAVA并不是纯面向对象的语言。Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的。但是我们在实际使用中经常需要将基本数据转化成对象,便于操作。比如:集合的操作中。例如使用Map对象要操作put()方法时,需要传入的参数是对象而不是基本数据类型。为了解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本数据类型对应的类统称为 包装类(Wrapper Class) 。

包装类均位于 java.lang 包,包装类和基本数据类型的对应关系如下表所示

基本数据类型 包装类
byte Byte
boolean Boolean
short Short
char Character
int Integer
long Long
float Float
double Double

在这八个类名中,除了Integer和Character类以后,其它六个类的类名和基本数据类型一直,只是类名的第一个字母大写即可。

包装类的用途

对于包装类说,这些类的用途主要包含两种:

  • 作为和基本数据类型对应的类类型存在,方便涉及到对象的操作。
  • 包含每种基本数据类型的相关属性如最大值、最小值等,以及相关的操作方法(这些操作方法的作用是在基本类型数据、包装类对象、字符串之间提供转化!)。

所有的包装类(Wrapper Class)都有共同的方法,他们是:

  • 基本类型转化成Integer对象

    • Integer int1 = new Integer(10); //在jdk9中已经废弃了
      Integer int2 = Integer.valueOf(20);
      
  • Integer对象转化成int

    • int a = int1.intValue();
      
  • 字符串转化成Integer对象

    • Integer int3 = Integer.parseInt("334");
      Integer int4 = new Integer("999");
      
  • Integer对象转化成字符串

    • String str1 = int3.toString();
      
  • 一些常见int类型相关的常量

    • System.out.println("int能表示的最大整数:"+Integer.MAX_VALUE);
      

自动装箱和拆箱

就是将基本类型和包装类进行自动的互相转换。JDK5.0后,将自动装箱/拆箱引入java中。

自动装箱的过程:每当需要一种类型的对象时,这种基本类型就自动地封装到与它相同类型的包装中。
自动拆箱的过程:每当需要一个值时,被装箱对象中的值就被自动地提取出来,没必要再去调用intValue()和doubleValue()方法。

自动装箱与拆箱的功能事实上是编译器来帮您的忙,编译器在编译时期依您所编写的语法,决定是否进行装箱或拆箱动作。

Integer i = 100;

相当于编译器自动为您作以下的语法编译:

Integer i = new Integer(100);

所以自动装箱与拆箱的功能是所谓的 “编译器蜜糖”(Compiler Sugar) ,虽然使用这个功能很方便,但在程序运行阶段您得了解Java的语义。例如下面的程序是可以通过编译的:

Integer i = null;
int j = i;

这样的语法在编译时期是合法的,但是在运行时期会有错误,因为这种写法相当于:

Integer i = null;
int j = i.intValue();

null 表示 i 没有参考至任何的对象实体,它可以合法地指定给对象参考名称。由于实际上 i 并没有参考至任何的对象,所以也就不可能操作 intValue() 方法,这样上面的写法在运行时会出现NullPointerException 错误。

缓存

自动装箱拆箱时,对于-128-127之间的值,编译器仍然会把它当做基本类型处理。

Integer h = 100;
Integer u = 100;
Integer h2 = 200;
Integer u2 = 200;
if(h==u){
   
  System.out.println("100等于");
}
if(h2==u2){
   
  System.out.println("200等于");
}

时间处理相关类

作为与我们息息相关的日期,在开发中也是很常见的。在程序中,日期的存储也是个数字,是个长整型的数字。0代表1970年1月1日 00:00:00,而我们处于东八区,所以为1970年1月1日 08:00:0 ,往前推,负数表示之前的时间,往后算正数表示之后的时间。

而在日常中,我们表示日期是使用字符串表示,如 1970年1月1日 08:15 、 1970/01/01 08:15
1970-01-01 08:15 等等,因此就涉及到 如何将长整型数与字符串互转的问题,这也是学习的重点。

版本8之前常用日期类

在标准Java类库中包含一个 Date 类。它的对象表示一个特定的瞬间,精确到毫秒。
Date分配一个Date对象,并初始化此对象为当前的日期和时间精确到毫秒。
Date 分配 Date 对象并初始化此对象,以表示自从标准基准时间(称为“历元(epoch)”,即 1970 年 1月 1 日 00:00:00 GMT)以来的指定毫秒数。

常见方法
System系统类 currentTimeMillis(): 当前时间
Date日期类 new Date() :当前时间
new Date(指定时间):指定时间
getTime(): 获取时间
setTime(指
  • 16
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值