HashSet集合
Posted hps123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HashSet集合相关的知识,希望对你有一定的参考价值。
java.util.Set接口 extends Collection接口
Set接口的特点:
1.不允许存储重复的元素
2.没有索引,没有带索引的方法,也不能使用普通的for循环遍历
java.util.HashSet集合 implements Set接口
HashSet特点:
1.不允许存储重复的元素
2.没有索引,没有带索引的方法,也不能使用普通的for循环遍历
3.是一个无序的集合,存储元素和取出元素的顺序有可能不一致
4.底层是一个哈希表结构(查询的速度非常的快)
public class Demo01Set { public static void main(String[] args) { Set<Integer> set = new HashSet<>(); //使用add方法往集合中添加元素 set.add(1); set.add(3); set.add(2); set.add(1); //使用迭代器遍历set集合 Iterator<Integer> it = set.iterator(); while (it.hasNext()){ Integer n = it.next(); System.out.println(n);//1,2,3 } //使用增强for遍历set集合 System.out.println("-----------------"); for (Integer i : set) { System.out.println(i); } }
哈希值
public class Person extends Object{ //重写hashCode方法 @Override public int hashCode() { return 1; } }
package demo03; import java.util.HashSet; /* 哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来得到地址,不是数据实际存储的物理地址) 在Object类有一个方法,可以获取对象的哈希值 int hashCode() 返回该对象的哈希码值。 hashCode方法的源码: public native int hashCode(); native:代表该方法调用的是本地操作系统的方法 */ public class Demo01HashCode { public static void main(String[] args) { //Person类继承了Object类,所以可以使用Object类的hashCode方法 Person p1 = new Person(); int h1 = p1.hashCode(); System.out.println(h1);//1967205423 | 1 Person p2 = new Person(); int h2 = p2.hashCode(); System.out.println(h2);//42121758 | 1 /* toString方法的源码: return getClass().getName() + "@" + Integer.toHexString(hashCode()); */ System.out.println(p1);//com.itheima.demo03.hashCode.Person@75412c2f System.out.println(p2);//com.itheima.demo03.hashCode.Person@282ba1e System.out.println(p1==p2);//false /* String类的哈希值 String类重写Obejct类的hashCode方法 */ String s1 = new String("abc"); String s2 = new String("abc"); System.out.println(s1.hashCode());//96354 System.out.println(s2.hashCode());//96354 System.out.println("重地".hashCode());//1179395 System.out.println("通话".hashCode());//1179395 } }
HashSet集合存储数据的结构(哈希表)
HashSet存储自定义类型
1 /* 2 HashSet存储自定义类型元素 3 4 set集合保证元素唯一: 5 存储的元素(String,Integer,...Student,Person...),必须重写hashCode方法和equals方法 6 7 要求: 8 同名同年龄的人,视为同一个人,只能存储一次 9 */ 10 public class Demo03HashSetSavePerson { 11 public static void main(String[] args) { 12 //创建一个hashset集合,存储person 13 HashSet<Person> set=new HashSet<>(); 14 Person p1=new Person("王五",18); 15 Person p2=new Person("王五",18); 16 Person p3=new Person("李四",19); 17 System.out.println(p1.hashCode()); //29049994 18 System.out.println(p2.hashCode()); //29049994 19 System.out.println(p1==p2); //false 20 System.out.println(p1.equals(p2)); //true 21 set.add(p1); 22 set.add(p2); 23 set.add(p3); 24 System.out.println(set); 25 } 26
28 public class Person { 29 private String name; 30 private int age; 31 public Person() { 32 } 33 34 public Person(String name, int age) { 35 this.name = name; 36 this.age = age; 37 } 38 39 public String getName() { 40 return name; 41 } 42 43 public void setName(String name) { 44 this.name = name; 45 } 46 47 public int getAge() { 48 return age; 49 } 50 51 public void setAge(int age) { 52 this.age = age; 53 } 54 55 @Override 56 public String toString() { 57 return "Person{" + 58 "name=‘" + name + ‘‘‘ + 59 ", age=" + age + 60 ‘}‘; 61 } 62 63 @Override 64 public boolean equals(Object o) { 65 if (this == o) return true; 66 if (o == null || getClass() != o.getClass()) return false; 67 Person person = (Person) o; 68 return age == person.age && 69 Objects.equals(name, person.name); 70 } 71 72 @Override 73 public int hashCode() { 74 75 return Objects.hash(name, age); 76 } 77 }
我们知道HashSet保证元素唯一,可是元素存放进去是没有顺序的,那么我们要保证有序,怎么办呢?
在HashSet下面有一个子类java.util.LinkedHashSet
,它是链表和哈希表组合的一个数据存储结构。
/* java.util.LinkedHashSet集合 extends HashSet集合 LinkedHashSet集合特点: 底层是一个哈希表(数组+链表/红黑树)+链表:多了一条链表(记录元素的存储顺序),保证元素有序 */ public class Demo04LinkedHashSet { public static void main(String[] args) { HashSet<String> set=new HashSet<>(); set.add("it"); set.add("abc"); set.add("abc"); set.add("hu"); System.out.println(set); //[abc, it, hu] 无序,不允许重复 LinkedHashSet<String> linked=new LinkedHashSet<>(); linked.add("abc"); linked.add("abc"); linked.add("it"); linked.add("hu"); System.out.println(linked); //[abc, it, hu] 有序的,不允许重复 } }
以上是关于HashSet集合的主要内容,如果未能解决你的问题,请参考以下文章
Java并发多线程编程——集合类线程不安全之HashSet的示例及解决方案