7. Set 接口
1.1 特性
繼承 Collection,但不允許重複,使用自己內部的一個排列機制,Set接口沒有引入新方法,所以Set就是一個Collection,只不過其行爲不同
1.2 HashSet
是最常用的,查詢速度最快,因爲 內部以HashMap來實現,所以插入元素不能保持插入次序
創建您自己的要添加到HashSet的類時,別忘了覆蓋 hashCode()和equals()
當兩個對象的equals方法返回true時,這兩個對象的hashCode應該相等
對象中用作equals比較標準的屬性,都應該用來計算hashCode值
1.3 Set 接口
取得hashCode值的方式
f爲每個有意義的屬性
爲了避免直接相加產生
偶然相等,各屬性乘以一個質數再相加:
f1.hashCode()*17+(int)f2*13
實例
HashSetTest2.java
HashSetTest.java
1.4 TreeSet
基於TreeMap,生成一個總是處於排序狀態的set,它實現了SortedSet接口,內部以 TreeMap來實現
TreeSet 是實現了SortedSet接口的唯一實現,TreeSet可以確保集合元素處於排序狀態
TreeSet 提供的方法
Comparator comparator() : 返回當前Set使用的Comparator
Object first():返回集合中的第一個元素
Object last():返回集合中的最後一個元素
Object lower(Object o): 返回集合中位於指定元素之前的元素
Object highter(Object o):返回集合中位於指定元素之後的元素
1.5 Comparable 接口
添加到TreeSet中的自定義類必須首先Comparable接口以實現自然排序
該接口中有一個 obj1.compareTo(Object obj2)方法,該方法返回正數,表明obj1大於obj2,該方法返回負數,表明obj1小於obj2,該方法返回0,表明obj1等於obj2
1.6 Comparator 接口
TreeSet 通過實現Comparable接口實現了自然排序,如果要實現定製排序,則需要爲TreeSet提供Comparator接口的實現
1.7 對set的選擇
1)HashSet的性能總比TreeSet好(特別是最常用的添加和查找元素操作)。
2)TreeSet存在的唯一原因是,它可以維持元素的排序狀態,所以只有當你需要一個排好序的Set時,才應該使用TreeSet。
3)對於插入操作,LinkedHashSet比HashSet略微慢一點:這是由於維護鏈表所帶來額外開銷造成的。不過,因爲有了鏈表,遍歷LinkedHashSet會比HashSet更快。
1.8 實例
package com.geek99.demo;
import java.util.HashSet;
import java.util.TreeSet;
public class Test {
public static void main(String[] args) {
test4();
}
static void test4(){
TreeSet<Person> ts = new TreeSet<Person>();
Person per = new Person(1,"tom",20);
Person per2 = new Person(3,"rose",19);
Person per3 = new Person(2,"kite",21);
ts.add(per);
ts.add(per2);
ts.add(per3);
System.out.println(ts);
}
static void test3(){
TreeSet<String> ts = new TreeSet<String>();
ts.add("A");
ts.add("E");
ts.add("D");
ts.add("C");
ts.add("B");
System.out.println(ts);
}
static void test2(){
HashSet<Person> hs =new HashSet<Person>();
Person per = new Person(1,"tom",20);
hs.add(per);
Person per2 = new Person(1,"tom",20);
hs.add(per2);
System.out.println(hs);
}
static void test1(){
HashSet<String> hs =new HashSet<String>();
hs.add("A");
hs.add("A");
hs.add("B");
System.out.println(hs);
}
}
class Person implements Comparable{
private int pid;
private String name;
private int age;
/*
@Override
public int hashCode() {
return pid;
}
@Override
public boolean equals(Object obj) {
Person per = (Person)obj;
return this.pid==per.pid;
}
*/
@Override
public String toString() {
return pid+","+name+","+age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + pid;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (pid != other.pid)
return false;
return true;
}
public Person() {
super();
}
public Person(int pid, String name, int age) {
super();
this.pid = pid;
this.name = name;
this.age = age;
}
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compareTo(Object o) {
Person per=(Person)o;
return this.age<per.age?-1:(this.age==per.age?0:1);
}
}
該博客教程視頻地址:http://geek99.com/node/1647