* Collection接口 :
*
|------List接口:
*
|------ArrayList(主要的实现类)、
*
|------LinkedList(对于频繁的插入、删除操作)、
*
|------Vector(古老的实现类、线程安全的,但效率要低于ArrayList)
*
|------Set接口:存储无序的,不可重复的元素.Set中常用的方法都是Collection下定义的。
*
|------HashSet(主要实现类)
|------LinkedHashSet
|------TreeSet
---------------------------------------------------------------------------------------------------------------
* 1.无序性:无序性!= 随机性。真正的无序性,指的是元素在底层存储的位置是无序的。
* 2.不可重复性:当向Set中添加进相同的元素的时候,后面的这个不能添加进去。
*
* 说明:要求添加进Set中的元素所在的类,一定要重写equals()和hashCode()方法。 进而保证Set中元素的不可重复性!
*
* Set中的元素时如何存储的呢?使用了哈希算法。
* 当向Set中添加对象时,首先调用此对象所在类的hashCode()方法,计算此对象的哈希值,此哈希值
* 决定了此对象在Set中的存储位置。若此位置之前没有对象存储,则这个对象直接存储到此位置。若此位置
* 已有对象存储,再通过equals()比较这两个对象是否相同。如果相同,后一个对象就不能再添加进来。 万一返回false呢,都存储。(不建议如此)
* >要求:hashCode()方法要与equals()方法一致。
1 @Test 2 public void testHashSet() { 3 Set set = new HashSet(); 4 set.add(123); 5 set.add(456); 6 set.add(new String("AA")); 7 set.add(new String("AA")); 8 set.add("BB"); 9 set.add(null);//可以添加null 10 Person p1 = new Person("GG", 23); 11 Person p2 = new Person("GG", 23); 12 System.out.println(p1.equals(p2)); 13 //可以观察添加hashCode方法和未添加后的差别 14 System.out.println(p1.hashCode()); 15 System.out.println(p2.hashCode()); 16 set.add(p1); 17 set.add(p2); 18 System.out.println(set.size()); 19 System.out.println(set); 20 }
------------------------------------------------------------------------------------------------------------
* 元素时,是按照添加进去的顺序遍历的!
*
* LinkedHashSet插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能。
1 @Test 2 public void testLinkedHashSet() { 3 Set set = new LinkedHashSet(); 4 set.add(123); 5 set.add(456); 6 set.add(new String("AA")); 7 set.add(new String("AA")); 8 set.add("BB"); 9 set.add(null); 10 11 Iterator iterator = set.iterator(); 12 while (iterator.hasNext()) { 13 System.out.println(iterator.next()); 14 } 15 }
* 2.可以按照添加进集合中的元素的指定的顺序遍历。像String,包装类等默认按照从小到大的顺序遍历。
* 3.当向TreeSet中添加自定义类的对象时,有两种排序方法:①自然排序②定制排序
* 4.自然排序:要求自定义类实现java.lang.Comparable接口并重写其compareTo(Object obj)的抽象方法
* 在此方法中,指明按照自定义类的哪个属性进行排序。
*
* 5.向TreeSet中添加元素时,首先按照compareTo()进行比较,一旦返回0,虽然仅是两个对象的此
* 属性值相同,但是程序会认为这两个对象是相同的,进而后一个对象就不能添加进来。
*
* >compareTo()与hashCode()以及equals()三者保持一致!
1 @Test 2 public void testTreeSet1() { 3 Set set = new TreeSet(); 4 // set.add(new String("AA")); 5 // set.add(new String("AA")); 6 // set.add("JJ"); 7 // set.add("GG"); 8 // set.add("MM"); 9 // 当Person类没有实现Comparable接口时,当向TreeSet中添加Person对象时,报ClassCastException 10 set.add(new Person("CC", 23)); 11 set.add(new Person("MM", 21)); 12 set.add(new Person("GG", 25)); 13 set.add(new Person("JJ", 24)); 14 set.add(new Person("KK", 20)); 15 set.add(new Person("DD", 20)); 16 // set.add("AA"); 17 for (Object str : set) { 18 System.out.println(str); 19 } 20 }
-------------------------------------------------------------------------------------------------------------
* TreeSet的定制排序: 见下面的步骤 compare()与hashCode()以及equals()三者保持一致!
1 @Test 2 public void testTreeSet2() { 3 // 1.创建一个实现了Comparator接口的类对象 4 Comparator com = new Comparator() { 5 // 向TreeSet中添加Customer类的对象,在此compare()方法中,指明是按照Customer 6 // 的哪个属性排序的。 7 @Override 8 public int compare(Object o1, Object o2) { 9 if (o1 instanceof Customer && o2 instanceof Customer) { 10 Customer c1 = (Customer) o1; 11 Customer c2 = (Customer) o2; 12 int i = c1.getId().compareTo(c2.getId()); 13 if (i == 0) { 14 return c1.getName().compareTo(c2.getName()); 15 } 16 return i; 17 } 18 return 0; 19 } 20 }; 21 // 2.将此对象作为形参传递给TreeSet的构造器中 22 TreeSet set = new TreeSet(com); 23 // 3.向TreeSet中添加Comparator接口中的compare方法中涉及的类的对象。 24 set.add(new Customer("AA", 1003)); 25 set.add(new Customer("BB", 1002)); 26 set.add(new Customer("GG", 1004)); 27 set.add(new Customer("CC", 1001)); 28 set.add(new Customer("DD", 1001)); 29 30 for (Object str : set) { 31 System.out.println(str); 32 } 33 } 34 35 36 @Test 37 public void testTreeSet3() { 38 39 TreeSet set = new TreeSet(new Comparator() { 40 public int compare(Object o1, Object o2) { 41 if (o1 instanceof Customer && o2 instanceof Customer) { 42 Customer c1 = (Customer) o1; 43 Customer c2 = (Customer) o2; 44 int i = c1.getId().compareTo(c2.getId()); 45 if (i == 0) { 46 return c1.getName().compareTo(c2.getName()); 47 } 48 return i; 49 } 50 return 0; 51 } 52 }); 53 set.add(new Customer("AA", 1003)); 54 set.add(new Customer("BB", 1002)); 55 set.add(new Customer("GG", 1004)); 56 set.add(new Customer("CC", 1001)); 57 set.add(new Customer("DD", 1001)); 58 59 for (Object str : set) { 60 System.out.println(str); 61 } 62 }
------------------------------------------------------------------以下为使用的类
1 class Customer { 2 private String name; 3 private Integer id; 4 public String getName() { 5 return name; 6 } 7 public void setName(String name) { 8 this.name = name; 9 } 10 public Integer getId() { 11 return id; 12 } 13 public void setId(Integer id) { 14 this.id = id; 15 } 16 public Customer(String name, Integer id) { 17 super(); 18 this.name = name; 19 this.id = id; 20 } 21 public Customer() { 22 super(); 23 } 24 @Override 25 public String toString() { 26 return "Customer [name=" + name + ", id=" + id + "]"; 27 } 28 @Override 29 public int hashCode() { 30 final int prime = 31; 31 int result = 1; 32 result = prime * result + ((id == null) ? 0 : id.hashCode()); 33 result = prime * result + ((name == null) ? 0 : name.hashCode()); 34 return result; 35 } 36 @Override 37 public boolean equals(Object obj) { 38 if (this == obj) 39 return true; 40 if (obj == null) 41 return false; 42 if (getClass() != obj.getClass()) 43 return false; 44 Customer other = (Customer) obj; 45 if (id == null) { 46 if (other.id != null) 47 return false; 48 } else if (!id.equals(other.id)) 49 return false; 50 if (name == null) { 51 if (other.name != null) 52 return false; 53 } else if (!name.equals(other.name)) 54 return false; 55 return true; 56 } 57 58 } 59 60 class Person implements Comparable{ 61 private String name; 62 private Integer age; 63 public String getName() { 64 return name; 65 } 66 public void setName(String name) { 67 this.name = name; 68 } 69 public Integer getAge() { 70 return age; 71 } 72 public void setAge(Integer age) { 73 this.age = age; 74 } 75 public Person() { 76 super(); 77 } 78 public Person(String name, Integer age) { 79 super(); 80 this.name = name; 81 this.age = age; 82 } 83 @Override 84 public String toString() { 85 return "Person [name=" + name + ", age=" + age + "]"; 86 } 87 //static int init = 1000; 88 @Override 89 public int hashCode() {//return age.hashCode() + name.hashCode();没下述的健壮性好。 90 final int prime = 31; 91 int result = 1; 92 result = prime * result + ((age == null) ? 0 : age.hashCode()); 93 result = prime * result + ((name == null) ? 0 : name.hashCode()); 94 return result; 95 //return init++;//不能这样用 96 } 97 @Override 98 public boolean equals(Object obj) { 99 if (this == obj) 100 return true; 101 if (obj == null) 102 return false; 103 if (getClass() != obj.getClass()) 104 return false; 105 Person other = (Person) obj; 106 if (age == null) { 107 if (other.age != null) 108 return false; 109 } else if (!age.equals(other.age)) 110 return false; 111 if (name == null) { 112 if (other.name != null) 113 return false; 114 } else if (!name.equals(other.name)) 115 return false; 116 return true; 117 } 118 //当向TreeSet中添加Person类的对象时,依据此方法,确定按照哪个属性排列。 119 @Override 120 public int compareTo(Object o) { 121 if(o instanceof Person){ 122 Person p = (Person)o; 123 //return this.name.compareTo(p.name); 124 //return -this.age.compareTo(p.age); 125 int i = this.age.compareTo(p.age); 126 if(i == 0){ 127 return this.name.compareTo(p.name); 128 }else{ 129 return i; 130 } 131 } 132 return 0; 133 } 134 135 }