[19/03/25-星期一] 容器_Collection(集合、容器)之Set(集合、安置,无顺序不可重复)

一、概念&方法

       Set接口继承自Collection,Set接口中没有新增方法,方法和Collection保持完全一致。。

      Set容器特点:无序、不可重复。无序指Set中的元素没有索引,只能遍历查找;不可重复指不允许加入重复的元素。更确切地讲,

新元素如果和Set中某个元素通过equals()方法对比为true,则不能加入;甚至,Set中也只能放入一个null元素,不能多个。

      Set常用的实现类有:HashSet、TreeSet等,我们一般使用HashSet。

 1 /*
 2 *测试set接口 hashset
 3  * 
 4  */
 5 package cn.sxt.collection;
 6 
 7 import java.util.HashSet;
 8 import java.util.Set;
 9 
10 public class Test_0325_HashSet {
11     public static void main(String[] args) {
12         Set<String> set=new HashSet<String>(); 
13         set.add("A");
14         set.add("B");
15         set.add("A");
16         //所有方法类似于linkList中的方法
17         System.out.println(set);//结果只会输出1个"A",而不是2个"A" 证明set中不可重复,即使null元素也只会加一次
18         set.remove("A");//移除"A"
19         System.out.println(set);
20         
21         Set<String> set2=new HashSet<String>(); 
22         set2.add("李");
23         set.addAll(set2);//把set2中的所有加入set中
24         System.out.println(set);
25         
26     }
29 }

 HashSet 

       是采用哈希算法实现,底层实际是用HashMap实现的(HashSet本质就是一个简化版的HashMap),查询效率和增删效率都比较高。

       我们发现里面有个map属性,这就是HashSet的核心秘密。我们再看add()方法,发现增加一个元素说白了就是在map中增加一个键值对,

键对象就是这个元素,值对象是名为PRESENT的Object对象。说白了,就是“往set中加入元素,本质就是把这个元素作为key加入到了内部的map中”。

      由于map中key都是不可重复的,因此,Set天然具有“不可重复”的特性。

 1 /*
 2  *  手工实现HashSet
 3  */
 4 package cn.sxt.collection;
 5 
 6 import java.util.HashMap;
 7 
 8 import javax.print.attribute.standard.PresentationDirection;
 9 
10 public class Test_0325_HashSet01 {
11     
12     public static void main(String[] args) {
13         Test_0325_HashSet01 set01=new Test_0325_HashSet01();
14         set01.add("a");
15         set01.add("b");
16         set01.add("c");
17         System.out.println(set01);
18         
19     }
20     
21     HashMap map;
22     
23     private static final Object PRESENT=new Object();
24     public Test_0325_HashSet01 () {
25         map=new HashMap();
26         
27     }
28     
29     public int size() {
30         return map.size();
31         
32     }
33     public void add(Object o) {
34         map.put(o,PRESENT );
35         
36     }
37     
38     public String toString() {
39         StringBuilder sb =new StringBuilder("[");
40         for (Object key : map.keySet()) {
41             sb.append(key+",");
42             
43             
44         }
45         sb.setCharAt(sb.length()-1, ']');
46         return sb.toString();
47     }
48     
49 }

TreeSet

        底层实际是用TreeMap实现的,内部维持了一个简化版的TreeMap,通过key来存储Set的元素。TreeSet内部需要

对存储的元素进行排序,因此,我们对应的类需要实现Comparable接口。这样,才能根据compareTo()方法比较对象之间

的大小,才能进行内部排序。

 【注】  (1)由于是二叉树,需要对元素做内部排序。 如果要放入TreeSet中的类没有实现Comparable接口,

               则会抛出异常:java.lang.ClassCastException。

               (2) TreeSet中不能放入null元素。

 1 /**
 2  * 
 3  */
 4 package cn.sxt.collection;
 5 
 6 import java.util.Set;
 7 
 8 import java.util.TreeSet;
 9 
10 
11 public class Test_0325_TreeSet {
12     public static void main(String[] args) {
13         Set<Integer> set=new TreeSet<Integer>(); 
14         set.add(300);
15         set.add(200);
16         set.add(600);
17         for (Integer m : set) {//按key递增的顺序输出
18             System.out.println(m);
19             
20         }
21         
22         Set<Emp2> set2=new TreeSet<>();
23         set2.add(new Emp2(102,"小李",2400));
24         set2.add(new Emp2(101,"小白",3600));
25         set2.add(new Emp2(102,"老黑",1200));
26         set2.add(new Emp2(100,"哈哈",2400));
27         
28         for (Emp2 emp2 : set2) {
29             System.out.println(emp2);
30             
31         }
32     
33 
34     }
35 
36 }
37 
38 class Emp2 implements Comparable<Emp2>{//雇员类,自定义按工资排序 Comparable:比较接口
39     int id;
40     String  name;
41     double salary;
42     
43     public Emp2(int id, String name, double salary) {
44         super();
45         this.id = id;
46         this.name = name;
47         this.salary = salary;
48     }
49     
50     public int compareTo(Emp2 o) { //负数:小于 ;0:等于;正数:大于
51         if (this.salary>o.salary) {
52             return 1;    
53         }else if (this.salary<o.salary) {
54             return -1;
55         }else { //工资相同比较id 
56             if (this.id>o.id) {
57                 return 1;
58             } else if(this.id<o.id) {
59                 return -1;
60             }else {
61                 return 0;
62             }
63         }
64     }
65     
66     public String toString() {
67         return "id:"+id+" name:"+name+" salary:"+salary;
68     }
69 }

 

posted @ 2019-03-24 12:20  ID长安忆  阅读(368)  评论(0)    收藏  举报