对于getClass和instanceof;hashCode和equalsqu

判断两个对象是否为同一类型,时常用到getclass 和 instanceof ,而这两个函数又是时常让人混淆。下面从一个例子说明两者的区别:

复制代码
public class Test_drive {
    
    public static void main(String[] args){ A a = new A(); B b = new B(); System.out.println(b.getClass().equals(A.class)); System.out.println(b.getClass().equals(B.class)); System.out.println(b instanceof A); System.out.println(b instanceof B); } } class A{ } class B extends A{ }
复制代码

在这里,上面四个语句分别输出:false , true , true , true

 

为什么呢?因为,instanceof判断是否是某一类型的实例时,该类型可以是父类或者接口。而getclass 用于判断准确的类型。

同时,在这里必须说明的是,getclass判断的是该变量实际指向的对象的类型(即运行时类型),跟声明该变量的类型无关。即,上面的代码中:

B b = new B();
改为
A a = new B();

各语句结果不变。


一、Java 常用包

java.lang--语言包:Java语言的基础类,包括Object类、Thread类、String、Math、System、Runtime、Class、Exception、Process等,是Java的核心类库

java.util--实用工具包:Scanner、Date、Calendar、LinkedList、Hashtable、Stack、TreeSet等;

java.NET--网络功能包:URL、Socket、ServerSocket等;

java.sql--数据库连接包:实现JDBC的类库;

java.io--输入输出包:提供与流相关的各种包;


二、Java 常用第三方jar包

log4j:一个非常常用的log日志jar包。

apache commons:包含了大量组件,很多实用小工具。

maven:项目管理的;

gson:Google 的Json解析库;

JUnit:java单元测试

jsoup:html解析;


三、Java常用接口

 Comparable ,Collection,Set, List, Map, Runnable Iterable Iterator 等等



2:泛型(掌握)
(1)泛型概述
是一种把明确类型的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。
(2)格式:
<数据类型>
注意:该数据类型只能是引用类型。
(3)好处:
A:把运行时期的问题提前到了编译期间
B:避免了强制类型转换
C:优化了程序设计,解决了黄色警告线问题,让程序更安全
(4)泛型的前世今生
A:泛型的由来
Object类型作为任意类型的时候,在向下转型的时候,会隐含一个转型问题
B:泛型类
C:泛型方法
D:泛型接口
E:泛型高级通配符
?
? extends E
? super E
(5)我们在哪里使用呢?
一般是在集合中使用。

4:静态导入(了解)
(1)可以导入到方法级别的导入
(2)格式:
import static 包名....类名.方法名;
(3)注意事项:
A:方法必须是静态的
B:如果多个类下有同名的方法,就不好区分了,还得加上前缀。
所以一般我们并不使用静态导入,但是一定要能够看懂。

5:可变参数(掌握)
(1)如果我们在写方法的时候,参数个数不明确,就应该定义可变参数。
(2)格式:
修饰符 返回值类型 方法名(数据类型... 变量) {}

注意:
A:该变量其实是一个数组名
B:如果一个方法有多个参数,并且有可变参数,可变参数必须在最后



hashcode与equals

在每个覆盖了equals方法的类中,与必须覆盖hashCode方法。不然,就违反了Object。hashCode的通用约定,导致该类无法结合所有基于散列的集合一起正常运作。这样的集合包括HashMap,HashSet和HashTable.

重写的散列函数必须是该实例值的一个函数,确信没有任何客户端会依赖于散列函数返回的确切值。



import java.util.HashMap;

class Apple {
    private String color;

    public Apple(String color) {
        this.color = color;
    }
@Override
public  int hashCode(){
        return this.color.length();
}
    public boolean equals(Object obj) {
        if (!(obj instanceof Apple))
            return false;
        if (obj == this)
            return true;
        return this.color.equals(((Apple) obj).color);
    }

}

public class Test {
    public static void main(String[] args) {
        Apple a1 = new Apple("green");
        Apple a2 = new Apple("red");
        // hashMap stores apple type and its quantity
        HashMap<Apple, Integer> m = new HashMap<Apple, Integer>();
        m.put(a1, 10);
        m.put(a2, 20);
        System.out.println(m.get(new Apple("green")));
    }
}

HashSet集合(掌握)
A:底层数据结构是哈希表(是一个元素为链表的数组)
B:哈希表底层依赖两个方法:hashCode()和equals()
  执行顺序:
首先比较哈希值是否相同
相同:继续执行equals()方法
返回true:元素重复了,不添加
返回false:直接把元素添加到集合
不同:就直接把元素添加到集合
C:如何保证元素唯一性的呢?
由hashCode()和equals()保证的
D:开发的时候,代码非常的简单,自动生成即可。
E:HashSet存储字符串并遍历
F:HashSet存储自定义对象并遍历(对象的成员变量值相同即为同一个元素)
(3)TreeSet集合
A:底层数据结构是红黑树(是一个自平衡的二叉树)
B:保证元素的排序方式
a:自然排序(元素具备比较性)
让元素所属的类实现Comparable接口
b:比较器排序(集合具备比较性)
让集合构造方法接收Comparator的实现类对象

返回值是10

这里测试是新建了一个Apple对象,值相同,但是默认的hashCode不同,注释掉@override后的方法

System.out.println(a1.hashCode());
System.out.println(a2.hashCode());



System.out.println(m.get(a1);返回是10,我们要验证的是equals和hashcode方法的作用。所以,每一个对象都有自己默认的不同的hashcode值,equals也不同,只有重写才能比较对象,系统默认找不到,只重写两个方法中的一个也不行。

猜你喜欢

转载自blog.csdn.net/qq_33330524/article/details/79173379