java 集合(四)HashSet 与 LinkedHashSet

查看源码:

HashSet底层new 了HashMap

哈希表的结构:

 

Demo:

 

package cn.sasa.demo2;

import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;

public class SetDemo {
    public static void main(String[] args) {
        //HashSet的特点
        //无序、无索引、元素不重复
        //取出元素可以使用iterator迭代器、增强for
        //主要的两个子类:HashSet/LinkedHashSet
        
        //====================HashSet===================
        //HashSet的数据结构:
        //HashSet是一个链表数组结合体,查询、增删都比较快
        //初始容量:数组长度默认16
        //加载因子:0.75
        //
        HashSet<String> shs = new HashSet<String>();
        shs.add("sasa");
        shs.add("aaa");
        shs.add("bbb");
        shs.add("ds");
        shs.add("aaa");//重复元素不存入
        
        System.out.println(shs.toString()); //[aaa, bbb, sasa, ds]  无序的,并没有按照存入的顺序存储
        
        System.out.println("=======================");
        //取出方式1
        Iterator<String> it = shs.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
        System.out.println("=======================");
        //取出方式2
        for(String s : shs) {
            System.out.println(s);
        }
        System.out.println("=======================");
        /**
         * 存入原理
         * 1、调用hashCode()算出哈希值
         * 2、查找容器中是否有与新元素一样的哈希值
         *      如果没有,直接存入,如果有,转第三步   
         * 3、新元素与该索引下的老元素利用equals方法对比,如果新元素.equals(老元素)返回true,说明重复,不存入,
         *  如果equals方法返回false,存入
         */
        //内存地址不同,调用Object的hashCode()返回不同的哈希值,重写hashCode()和equals方法判断对象是否相同
        HashSet<Person> personSet = new HashSet<Person>();
        personSet.add(new Person("sa",11));
        personSet.add(new Person("sa",11));
        personSet.add(new Person("hi",12));
        personSet.add(new Person("lalala",13));
        //personSet.add(null);
        //personSet.add(null);//HashSet里可以存null值,但取出来的时候因为类型转换不成功,会报错
        System.out.println(personSet.size());//3
        System.out.println("=======================");
        Iterator<Person> itPer = personSet.iterator();
        while(itPer.hasNext()) {
            System.out.println(itPer.next().getName());
        }
        
        System.out.println("===================LinkedHashSet===================");
        LinkedHashSet<String> intLinhss = new LinkedHashSet<String>();
        intLinhss.add("sasa");
        intLinhss.add("aaa");
        intLinhss.add("bbb");
        intLinhss.add("ds");
        intLinhss.add("aaa");//重复元素不存入
        for(String s : intLinhss) {
            System.out.println(s);
        }
        //输出:
        //sasa
        //aaa
        //bbb
        //ds
        //LinkedHashSet 双向链表结构,有序的
    }
}

 

package cn.sasa.demo2;

public class Person {
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    
    public Person(String name,int age) {
        this.name = name;
        this.age = age;
    }
    //重写equals
    public boolean equals(Object obj) {
        if(this == obj) 
            return true;
        if(obj == null)
            return false;
        if(obj instanceof Person) {
            Person p = (Person)obj;
            if(this.name == p.getName() && this.age == p.getAge() ) {
                return true;
            }else {
                return false;
            }
        }
        return false;
    }
    
    //重写hashCode() 为了尽量避免hashCode出现同样值的概率,age * 31,后面的数可以是除了1和0之外的数
    public int hashCode() {
        return this.name.hashCode() + age * 31;
    }
}

 

posted @ 2018-12-20 09:50  SasaL  Views(245)  Comments(0Edit  收藏  举报