首页 > 代码库 > 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         }
HashSet无序

技术分享

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自然排序

技术分享

构造方法:

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;
对Student类中的CompareTo方法重写

如果使用 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         }
HashMap

 

 

 技术分享

 

Java学习:集合类2