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; } }