首页 > 代码库 > Java学习:集合类2
Java学习:集合类2
Set
HashSet
特点:元素唯一,但是无序。
如何保证元素的唯一性的呢(分析源码)?
通过简单的分析,我们知道HashSet集合保证元素的唯一性和add()方法相关。
如何我们想深入的了解,就必须看add()方法的源码,看它的底层依赖什么内容?
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {...}
左边:e.hash == hash
比较对象的哈希值。
右边:((k = e.key) == key || key.equals(k))
左边:(k = e.key) == key
比较对象的地址值。
右边:key.equals(k)
比较的是对象的内容是否相同。默认情况下比较的是地址值
结论:
底层数据结构是哈希表。
哈希表依赖两个方法:hashCode()和equals()
执行流程:
首先判断哈希值是否相同,如果不同,就直接添加到集合。
如果相同,继续执行equals(),看其返回值,
如果是false,就直接添加到集合。
如果是true,说明元素重复不添加。
使用:
如果你看到哈希结构的集合,就要考虑可能需要重写这两个方法。
如果真要重写,自动生成即可。
HashSet练习代码如下
1 //创建一个HashSet集合 2 HashSet<String> set = new HashSet<String>(); 3 4 //给集合中添加元素 5 set.add("a"); 6 set.add("b"); 7 set.add("c"); 8 set.add("d"); 9 set.add("e"); 10 set.add("f"); 11 12 //遍历集合 13 /** 14 * HashSet集合特点: 15 * 1.元素无序 16 * 2.元素唯一 17 */ 18 for (String string : set) { 19 System.out.println(string); 20 }
TreeSet
元素顺序:使用元素的自然顺序对元素进行排序,或者根据创建 set时提供的 Comparator进行排序,
具体取决于使用的构造方法。
底层算法:二叉树。
1 TreeSet<Integer> ts = new TreeSet<Integer>(); 2 3 //给集合中存储元素 4 //(20,18,23,22,17,24,19,18,24) 5 ts.add(20); 6 ts.add(18); 7 ts.add(23); 8 ts.add(22); 9 ts.add(17); 10 ts.add(24); 11 ts.add(19); 12 ts.add(18); 13 ts.add(24); 14 15 //遍历集合 16 for (Integer integer : ts) { 17 System.out.println(integer); 18 }
构造方法:
TreeSet()
构造一个新的空 set,该 set 根据其元素的自然顺序进行排序。
TreeSet(Comparator<? super E> comparator)
构造一个新的空 TreeSet,它根据指定比较器进行排序。
如果想使用自然排序的方法对对象进行排序,需要在对象类中重写compareTo方法
重写方法如下:
1 public int compareTo(Student s) { 2 //就是写的是元素的比较规则,由你自己去动手写出 3 //按照学生的年龄进行排序 4 /** 5 * 两个对象进行比较: 6 * s 7 * this 8 */ 9 int num = this.age - s.age; 10 //判断年龄是否相同,如果相同比较姓名 11 /** 12 * 写这个比较规则的时候注意两点: 13 * 1.他有主要条件,先按照主要条件进行排序 14 * 2.如果主要条件相同,就需要你自己分析出来他的次要条件,再去按照次要条件进行比较 15 */ 16 17 int num2 = num==0?this.name.compareTo(s.name):num; 18 return num2;
如果使用 set时提供的 Comparator进行排序,则需要创建一个Comparator接口的实现类对象。
案例如下:
1 TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() { 2 public int compare(Student s1, Student s2) { 3 int num = s1.getAge() - s2.getAge(); 4 int num2 = num==0?s1.getName().compareTo(s2.getName()):num; 5 return num2; 6 } 7 }); 8 9 //创建对象存入集合 10 Student s = new Student("guodegang", 50); 11 Student s6 = new Student("liuyifei", 50); 12 Student s2 = new Student("zhangxueyou", 55); 13 Student s3 = new Student("amu", 45); 14 Student s4 = new Student("tf-boys", 18); 15 Student s5 = new Student("wangfeng", 49); 16 17 ts.add(s); 18 ts.add(s2); 19 ts.add(s3); 20 ts.add(s4); 21 ts.add(s5); 22 ts.add(s6); 23 24 //遍历集合 25 for (Student student : ts) { 26 System.out.println(student); 27 }
HashSet与TreeSet的相同点与不同点
相同点:
单列集合,元素不可重复
不同点:
1. 底层存储的数据结构不同
HashSet底层用的是HashMap哈希表结构存储,而TreeSet底层用的是二叉树结构存储
2.存储时保证数据唯一性依据不同
HashSet是通过复写hashCode()方法和equals()方法来保证的,而TreeSet通过Compareable接口的compareTo()方法来保证的
3.有序性不一样
HashSet无序,TreeSet有序
Map
将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
Map接口中的方法概述(创建集合测试方法):
A:删除功能
void clear():移除集合中的所有键值对元素
V remove(Object key):根据键移除键值对元素,并返回值
B:判断功能
boolean containsKey(Object key):判断集合中是否包含指定的键
boolean containsValue(Object value):判断集合中是否包含指定的值
boolean isEmpty():判断集合是否为空
C:获取功能
Set<Map.Entry<K,V>> entrySet():获取键值对对象的集合,遍历键值对对象,
利用getKey(),getValue()取出键和值
V get(Object key):根据键获取值
Set<K> keySet():获取所有的键
Collection<V> values():获取所有的值
D:添加功能
V put(K key,V value):集合添加键值对
E:长度功能
int size():键值对对数。
HashMap
2.1元素顺序:元素顺序不可预测
2.2底层算法:哈希算法
2.3对键没有要求(仅仅相对于TreeMap来说)
练习代码如下:
1 //创建学生对象 2 Student s1 = new Student("杰克逊", 60); 3 Student s2 = new Student("孙楠", 50); 4 Student s3 = new Student("权志龙", 30); 5 Student s4 = new Student("权志龙", 30); 6 7 //将对象存入集合 8 hm.put(s1, "美国"); 9 hm.put(s2, "中国"); 10 hm.put(s3, "韩国"); 11 hm.put(s4, "中国"); 12 13 //遍历集合 14 Set<Student> keys = hm.keySet(); 15 for (Student s : keys) { 16 System.out.println(s+" "+hm.get(s)); 17 }
Java学习:集合类2