[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 }

浙公网安备 33010602011771号