java学习初探十三之集合—Set详解
2017-09-14 23:07
489 查看
1.哈希表/散列表
HashSet底层实际上是一个HashMap。HashMap底层是哈希表/散列表。
哈希表是数组和单向链表的集合。
哈希表本质是一个数组,只不过这个数组中的每个元素又是个单向链表。类似于现实世界中的字典。
final int hash这个是哈希值,是通过key调用hashCode方法得到的值,再通过“哈希算法”得到的值。在单向链表中,每个节点的哈希值是相同的。代表的是数组的下标。注,不同key的获得的hashCode可能相同,也可能不相同。
2.HashSet详解
(1)HashSet底层实际上是一个HashMap,HashMap底层采用了哈希表数据结构。
(2)哈希表又叫散列表,哈希表底层是一个数组,这个数组中每个元素是一个单向链表。每个单向链表都有一个独一无二的hash值,代表数组的下标。在某个单向链表中的每一个节点上的hash值是相等的。hash值实际上是key调用hashCode方法,再通过“hash function”转换成的值。
(3)如何向哈希表中添加元素:
先调用被存储key的hashCode方法,经过某个算法得到hash值,如果在这个哈希表中不存在这个hash值,则直接加入元素。如果该hash值已经存在,继续调用key之间的equals方法,如果equals方法返回false,则将该元素添加。如果equals返回true,则放弃添加该元素。
(4)HashSet其实是HashMap中的key部分。HashSet有什么特点,HashMap中的key应该具有相同的特点。
(5)HashMap和HashSet初始化容量都是16,默认加载因子是0.75。
关于往Set集合中存储的元素,该元素的hashCode和equals方法:
HashMap中有一个put方法,put(key,value) key是无序不可重复的。
结论:存储在HashSet集合或HashMap集合key部分的元素,需要同时重写public int hashCode()()和public boolean equals(Object o)方法。
hashCode目的:让散列分布均匀。
3.SortedSet详解
(1)无序不可重复,但是存进去的元素可以按照元素大小顺序自动排序。
数据结构:二叉树
(2)实现Comparable接口
SortedSet集合存储元素为什么可以自动排序?
因为被存储的元素实现了Comparable接口,
SUN编写的TreeSet集合在添加元素的时候,会调用compareTo方法,完成比较。
(3)java.util.Comparator
SortedSet集合做到排序还有另外一个方法java.util.Comparator相比Comparable更为灵活,耦合度较低,推荐使用Copmparator比较器
HashSet底层实际上是一个HashMap。HashMap底层是哈希表/散列表。
哈希表是数组和单向链表的集合。
哈希表本质是一个数组,只不过这个数组中的每个元素又是个单向链表。类似于现实世界中的字典。
final int hash这个是哈希值,是通过key调用hashCode方法得到的值,再通过“哈希算法”得到的值。在单向链表中,每个节点的哈希值是相同的。代表的是数组的下标。注,不同key的获得的hashCode可能相同,也可能不相同。
2.HashSet详解
(1)HashSet底层实际上是一个HashMap,HashMap底层采用了哈希表数据结构。
(2)哈希表又叫散列表,哈希表底层是一个数组,这个数组中每个元素是一个单向链表。每个单向链表都有一个独一无二的hash值,代表数组的下标。在某个单向链表中的每一个节点上的hash值是相等的。hash值实际上是key调用hashCode方法,再通过“hash function”转换成的值。
(3)如何向哈希表中添加元素:
先调用被存储key的hashCode方法,经过某个算法得到hash值,如果在这个哈希表中不存在这个hash值,则直接加入元素。如果该hash值已经存在,继续调用key之间的equals方法,如果equals方法返回false,则将该元素添加。如果equals返回true,则放弃添加该元素。
(4)HashSet其实是HashMap中的key部分。HashSet有什么特点,HashMap中的key应该具有相同的特点。
(5)HashMap和HashSet初始化容量都是16,默认加载因子是0.75。
import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class SetTest { public static void main(String[] args) { //创建Set集合 Set s=new HashSet(); //无序不可重复 s.add(1); 4000 s.add(1); s.add(100); s.add("ok"); s.add(85); s.add(88); //遍历 Iterator it=s.iterator(); while(it.hasNext()) { System.out.println(it.next());//1 100 85 88 ok } } }
关于往Set集合中存储的元素,该元素的hashCode和equals方法:
HashMap中有一个put方法,put(key,value) key是无序不可重复的。
结论:存储在HashSet集合或HashMap集合key部分的元素,需要同时重写public int hashCode()()和public boolean equals(Object o)方法。
hashCode目的:让散列分布均匀。
import java.util.HashSet; import java.util.Set; public class SetTset02 { public static void main(String[] args) { //创建集合 Set es=new HashSet(); Employee e1=new Employee("1000", "JACK"); Employee e2=new Employee("1000", "JACK"); Employee e3=new Employee("2000", "JIM"); Employee e4=new Employee("2001", "SUN"); Employee e5=new Employee("3000", "ROSE"); Employee e6=new Employee("3001", "COOK"); //添加元素 es.add(e1); es.add(e2); es.add(e3); es.add(e4); es.add(e5); es.add(e6); //重写hashCode和equals方法前 查看集合元素hash值和元素个数 System.out.println(e1.hashCode());//366712642 System.out.println(e2.hashCode());//1829164700 System.out.println(es.size());//6 //重写hashCode和equals方法后 查看集合元素hash值和元素个数 System.out.println(e1.hashCode());//1507423 System.out.println(e2.hashCode());//1507423 System.out.println(es.size());//5 } } //根据现实的业务逻辑得知:该公司员工编号是:1000-9999 class Employee{ //编号 String no; //姓名 String name; //Constructor Employee(String no,String name){ this.no=no; this.name=name; } //重写hashCode方法 public int hashCode() { //以员工编号分组 return no.hashCode(); } //重写equals方法 //如果员工编号相同,并且名字相同,则是同一个人 public boolean equals(Object o) { if(this==o) return true; if(o instanceof Employee) { Employee e=(Employee)o; if(e.no.equals(this.no)&&e.name.equals(this.name)) { return true; } } return false; } }
3.SortedSet详解
(1)无序不可重复,但是存进去的元素可以按照元素大小顺序自动排序。
数据结构:二叉树
import java.util.Date; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Iterator; import java.util.SortedSet; import java.util.TreeSet; public class SetTest03 { public static void main(String[] args) throws ParseException { //创建集合 SortedSet ss=new TreeSet(); //添加元素 ss.add(10);//自动装箱 ss.add(20); ss.add(15); ss.add(30); ss.add(25); ss.add(9); //遍历 Iterator it=ss.iterator(); while (it.hasNext()) { System.out.println(it.next());//9 10 15 20 25 30 } //String SortedSet strs=new TreeSet(); strs.add("JACK"); strs.add("SUN"); strs.add("COOK"); strs.add("LUCY"); strs.add("KING"); //遍历 Iterator its=strs.iterator(); while (its.hasNext()) { System.out.println(its.next());//COOK JACK KING LUCY SUN } //Date String t1="2008-08-08"; String t2="2009-08-08"; String t3="2008-09-08"; String t4="2008-08-09"; String t5="2012-08-08"; SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); Date date1=sdf.parse(t1); Date date2=sdf.parse(t2); Date date3=sdf.parse(t3); Date date4=sdf.parse(t4); Date date5=sdf.parse(t5); SortedSet strse=new TreeSet(); strse.add(date1); strse.add(date2); strse.add(date3); strse.add(date4); strse.add(date5); //遍历 Iterator itst=strse.iterator(); while (itst.hasNext()) { Object element=itst.next(); if(element instanceof Date) { Date d=(Date)element; System.out.println(sdf.format(d)); /*输出结果 2008-08-08 2008-08-09 2008-09-08 2009-08-08 2012-08-08 */ } } } }
(2)实现Comparable接口
SortedSet集合存储元素为什么可以自动排序?
因为被存储的元素实现了Comparable接口,
SUN编写的TreeSet集合在添加元素的时候,会调用compareTo方法,完成比较。
import java.util.Iterator; import java.util.SortedSet; import java.util.TreeSet; public class SetTest04 { public static void main(String[] args) { SortedSet users=new TreeSet(); User u1=new User(15); User u2=new User(16); User u3=new User(25); User u4=new User(13); User u5=new User(14); //添加元素 users.add(u1); users.add(u2); users.add(u3); users.add(u4); users.add(u5); //实现java.lang.Comparable接口前 遍历 Iterator it=users.iterator(); while (it.hasNext()) { System.out.println(it.next()); /* * java.lang.ClassCastException: * User cannot be cast to java.lang.Comparable */ } //实现java.lang.Comparable接口前 遍历 Iterator it2=users.iterator(); while (it2.hasNext()) { System.out.println(it2.next()); /* * User[age=13] User[age=14] User[age=15] User[age=16] User[age=25] */ } } } class User implements Comparable{ int age; User(int age){ this.age=age; } public String toString() { return "User[age="+age+"]"; } //实现java.lang.Comparable接口中的compareTo方法 //该方法程序员负责实现,SUN提供的程序已经调用了该方法 //需求:按照User的age年龄排序 public int compareTo(Object o) { //编写一个比较规则 int age1=this.age; int age2=((User)o).age; return age1-age2; } }
(3)java.util.Comparator
SortedSet集合做到排序还有另外一个方法java.util.Comparator相比Comparable更为灵活,耦合度较低,推荐使用Copmparator比较器
import java.util.Comparator; import java.util.Iterator; import java.util.SortedSet; import java.util.TreeSet; public class SetTest05 { public static void main(String[] args) { //创建TreeSet集合的时候提供一个比较器 So a35e rtedSet products=new TreeSet(new ProductComparator()); //还可以用下面匿名内部类的方式实现比较器,不推荐使用,因为毕竟器不能得到重复利用 /* SortedSet products=new TreeSet(new Comparator() { public int compare(Object o1, Object o2) { double price1=((Product)o1).price; double price2=((Product)o2).price; if(price1==price2) { return 0; }else if(price1>price2) { return 1; }else { return -1; } } }); */ Product p1=new Product(3.4); Product p2=new Product(4.0); Product p3=new Product(2.0); Product p4=new Product(3.0); Product p5=new Product(5.0); //添加元素 products.add(p1); products.add(p2); products.add(p3); products.add(p4); products.add(p5); //遍历 Iterator it =products.iterator(); while (it.hasNext()) { System.out.println(it.next()); /* * 输出结果 * 2.0 3.0 3.4 4.0 5.0 */ } } } class Product{ double price; public Product(double price) { this.price=price; } public String toString() { return price+""; } } //单独写一个比较器 class ProductComparator implements Comparator{ //重写: //需求:按照商品价格排序 public int compare(Object o1, Object o2) { double price1=((Product)o1).price; double price2=((Product)o2).price; if(price1==price2) { return 0; }else if(price1>price2) { return 1; }else { return -1; } } }
相关文章推荐
- java学习初探十三之集合—Map详解
- java学习初探十三之集合Collection常用方法
- java学习初探十三之集合
- Java 集合学习 之 Set 集合详解
- CoreJava学习4——集合之Set和Map
- 黑马程序员java学习—集合框架List和Set
- java学习之路-----集合(类集)-------set
- Map、Set、Iterator迭代详解与Java平台的集合框架
- Map、Set、Iterator迭代详解与 Java平台的集合框架
- Java集合(set,map)的排序和HashCode方法详解
- Java集合源码学习(11)_Set接口的实现LinkedHashSet
- Java学习笔记----------集合Set
- 13. Java类集 Part 1(类集、Collection接口、List接口、Set接口、SortedSet接口、集合的输出) ----- 学习笔记
- JAVA三种集合LIST、SET、MAP ——详解
- Java集合排序及java集合类详解:Set
- java学习笔记:集合框架之TreeSet
- Java学习之容器上(Collection接口常用方法,Iterator接口,使用foreach循环遍历Collection集合元素,Set集合通用知识(Hashset类,hashcode()与LinkedHashSet类))
- JAVA基础学习之 Map集合、集合框架工具类Collections,Arrays、可变参数、List和Set集合框架什么时候使用等(4)
- 黑马程序员_JAVA学习日记_JAVA中API:集合框架1(Collection,List,Set及其子类和迭代器的应用)
- Java学习第14天:集合框架零接触和基本理解(List和Set)