java集合框架之Set------02_01 HashSet LinkedHashSet

java 中的Set集合是无序的,并且其中不能包含重复的元素。这里的序是指,存入的顺序和取出的顺序是否一致,如果一致则为有序否则则为无序。
Set接口主要是实现类有三个,HashSet,TreeSet和EnumSet。

在HashSet中,哈希值是一个很重要的概念,下面通过例子说明:

class AA{
    
}
public class HashCodeDemo_02 {
    public static void main(String[] args){
        HashSet hs = new HashSet();
        hs.add(new AA());
        hs.add(new AA());
        hs.add(new AA());
        hs.add(new AA());
        System.out.println(hs);
    }
} 
输出为:
java集合框架学习.AA@8071a97
java集合框架学习.AA@55fe910c
java集合框架学习.AA@a62b39f
java集合框架学习.AA@3be4d6ef 

@后面的就是hash值。
在java中, HashSet中的每一个元素在存储的时候,都是用hashCode来计算它的存储位置。 当需要查询集合中的某个元素的时候,hash算法可以直接根据该元素的hashCode计算出该元素的存储位置,可以类比数据按下表存取。
HashSet中每个能存储元素的槽位通常称为桶,如果多个元素的hashCode值相同,但是通过equals方法比较又返回false,则就需要在一个桶里放多个元素,导致HashSet性能下降。这种情况要尽量避免。
举一个例子:
import java.util.HashSet;
class A{
    public boolean equals(Object obj){
        return true;
    }
}
class B{
    public int hashCode(){
        return 1;
    }
}
class C{
    public boolean equals(Object obj){
        return true;
    }
    public int hashCode(){
        return 2;
    }
}
public class HashSetDemo1 {
    public static void main(String[] args){
        HashSet hs = new HashSet();
        hs.add(new A());
        hs.add(new A());
        hs.add(new B());
        hs.add(new C());
        hs.add(new C());
        Iterator it = hs.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
}  
运行结果如下:
java集合框架学习.B@1
java集合框架学习.C@2
java集合框架学习.A@2cdb03a1
java集合框架学习.A@3be4d6ef

一般在自定义类中,如果重写equals方法,对应的也会重写hashCode方法。
在存入一个新对象保证唯一性的时候,hashCode方法和equals方法的调用情况为:
如果hashCode一样,调用equals方法,如果equals返回false,元素不同可以存储。
如果hashCode不一样,不调用equals方法进行比较。

所以,高效的hashCode,才能保证高效的HashSet。
同样的,LinkedHashSet也是根据hashCode值来决定元素的存储位置,但它同时使用链表维护元素的次序。也就是说,当遍历LinkedHashSet时,将会按照元素的添加顺序访问集合里的元素。同样,LinkedHashSet也不存在相同的元素。
示例如下:
import java.util.LinkedHashSet;
public class LinkedHashSetDemo {
    public static void main(String[] args){
        LinkedHashSet lhs = new LinkedHashSet();
        lhs.add("zhang");
        lhs.add("wang");
        lhs.add("li");
        System.out.println(lhs);
        lhs.remove("zhang");
        lhs.add("zhang");
        System.out.println(lhs);
    }
} import java.util.LinkedHashSet;
public class LinkedHashSetDemo {
    public static void main(String[] args){
        LinkedHashSet lhs = new LinkedHashSet();
        lhs.add("zhang");
        lhs.add("wang");
        lhs.add("li");
        System.out.println(lhs);
        lhs.remove("zhang");
        lhs.add("zhang");
        System.out.println(lhs);
    }
} 


输出为:
[zhang, wang, li]
[wang, li, zhang] 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值