Java的对象容器Collection
Collection的子接口有Set(元素不可重复),List(元素可重复有索引),Queue(队列).
二.Set
set关注唯一性也就是元素不可重复,以equals(),hashcode()来判断。分为HashSet,LinkedHashSet,TreeSet
1.HashSet无序且不可排序,使用对象的hashcode插入
2.LinkedHashSet,有序的HashSet,通过双向链接来维持对象之间的关系,顺序是元素的插入顺序。
3.TreeSet,可排序的Set(另外还有一个TreeMap),使用红黑树的结构,将元素按自然顺序做升序排列,可以实现Comparable或Comparator接口来自定义排序规则。
public class Employee implements Comparable{
private String name;
private int age;
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;
}
public Employee(){
}
public Employee(String name) {
super();
this.name = name;
}
public Employee(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Employee [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Object o) {
Employee emp = (Employee)o;
return this.name.compareTo(emp.name);
}
}
public class SetTest {
public static void main(String[] args) {
//addItem();
//addEmp();
//addEmpToLinkedHashSet();
addEmpToTreeSet();
}
/**
* HashSet的重复判断是这样的:
* hashcode不同,对象一定不同
* hashcode相同,判断==(比地址)
* ==不同,再比较equals
* hashcode()&&(==||equals()),满足此条件(hashcode相同并且(==,equals其中一个相同))就表明2对象相同
*/
static void addItem(){
Set<string> set = new HashSet<string>();
set.add("wanghaijun");
set.add("mayu");
set.add("luxiangdong");
System.out.println("Size of Set: "+set.size());
set.add("wanghaijun");//Set中的元素不可重复,所以此句代码添加不进元素
System.out.println("Size of Set: "+set.size());
set.add(new String("liqiang"));
set.add(new String("liqiang"));
System.out.println("Size of Set: "+set.size());
}
/**
* 自定义类型作为HashSet的元素时,如果不以默认的比较规则(地址hashcode)
* 必须重写hashcode和equals方法,并且比较规则要一致
*/
static void addEmp(){
Set<employee> set = new HashSet<employee>();
// 这2个Employee对象的hashcode是地址码,所以不同,我们可以重写hash和equals方法
set.add(new Employee("wanghaijun"));
set.add(new Employee("wanghaijun"));
System.out.println(set.size());
//printSet(set);
}
static void addEmpToLinkedHashSet(){
Set<employee> set = new LinkedHashSet<employee>();//按插入顺序排序
set.add(new Employee("wanghaijun"));
set.add(new Employee("liqiang"));
set.add(new Employee("mayu"));
printSet(set);
}
static void printSet(Set set){
// 方式1
Iterator iter = set.iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
// 方式2
for(Object o: set){
System.out.println(o);
}
}
static void addEmpToTreeSet(){
// 自定义TreeSet的插入顺序规则
// 方式1:构造TreeSet的时候以Comparator对象做为构造参数
/*Set<employee> set = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Employee emp1 = (Employee)o1;
Employee emp2 = (Employee)o2;
return emp1.getName().compareTo(emp2.getName());
}
});*/
// 方式2:自定义类型实现Comparable接口
Set<employee> set = new TreeSet<employee>();
set.add(new Employee("wanghaijun"));
set.add(new Employee("mayu"));
set.add(new Employee("luxiangdong"));
printSet(set);
}
}</employee></employee></employee></employee></employee></employee></employee></string></string>
addItem方法:
第一个size是3
第二个是3,因为set.add("wanghaijun");跟前面重复了,
第三个是4,因为set.add(new String("liqiang"));跟前面重复了
HashSet的重复判断是这样的:
hashcode不同,对象一定不同
hashcode相同,判断==(比地址)
==不同,再比较equals
伪代码就是:hashcode()&&(==||equals()),满足此条件(hashcode相同并且(==,equals其中一个相同))就表明元素是相同的