------- android培训、java培训、期待与您交流! ----------
Set 接口
|----- Set: 元素是无序的(存入和取出的顺序不一定一致), 元素不可以重复。
|---- HashSet: 底层数据结构是哈希表。
HashSet 是如何保证元素的唯一性呢?
通过元素的 hashCode 和 equals 来完成。如果元素的 hashCode 值相同,才会判断equals 是否为 true 。如果元素的 hashCode 值不同,不会调用 equals 。
|---- TreeSet:可以对 Set 集合中的元素进行排序。底层数据结构是二叉树。
保证元素的唯一性的依据: compareTo 方法 return 0 。
TreeSet 的第一种排序方式: 让元素自身具备比较性。 元素需要实现 comparable 接口,覆盖 compareTo 方法。
TreeSet 的第二种排序方式: 当元素本身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。
在集合初始化时,就有了比较方式。
1. Set集合所包含的方法与 Collection 集合一致。只是行为不同,Set 集合不包含重复元素。
2. Set 判断两个对象相同不是使用 == 运算符,而是根据 equals 方法。 Set 集合至少完全适用 HashSet、 TreeSet、 EnumSet 三个实现类。
例1:Set 的集合的特性展示。
import java.util.Set;
import java.util.HashSet;
class Test
{
public static void main(String[] args)
{
Set books = new HashSet();
books.add(new String("java01")); // 添加两个字符串对象
books.add(new String("java01"));
System.out.println(books);
}
}
运行结果:
[java01]
范例分析: Set 集合不允许包含相同的元素。
例2: Set 的集合的特性展示。
import java.util.Set;
import java.util.HashSet;
class Test
{
public static void main(String[] args)
{
Set books = new HashSet();
books.add(new String("java01"));
boolean result = books.add(new String("java01")); // 再次添加一个字符串对象,两个字符串对象通过 equals 方法比较相等,所以添加失败,返回 false。
System.out.println(result);
System.out.println(books);
}
}
运行结果: false
[java01]
范例分析: Set 判断两个对象相同不是使用 == 运算符,而是根据 equals 方法。 如果只要两个对象用 equals 方法比较返回 true ,Set 就不会接受两个对象。
HashSet 类
1. 不能保证元素的排列顺序,顺序可能会发生变化。
2. HashSet 不是同步的,如果多个线程同时访问一个 Set 集合,如果多个线程同时访问一个 HashSet ,如果有 2 条或者 2 条以上线程同时修改了 HashSet 集合时,必须通过代码来保证其
同步。
3. 集合元素值可以是 null 。
4. HashSet 集合采用 hash 算法来决定元素的存储位置。
元素判断: HashSet 集合判断两个元素相等的标准是两个对象通过 hashCode() 和equals() 方法.
例3:往hashSet集合中存入自定对象,姓名和年龄相同为同一个人,重复元素。
import java.util.HashSet;
import java.util.Iterator;
class Test
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
HashSet h = new HashSet();
h.add(new Person("java01",11));
h.add(new Person("java02",12));
h.add(new Person("java03",13));
h.add(new Person("java02",12));
h.add(new Person("java04",14));
Iterator i = h.iterator();
while(i.hasNext())
{
Person p = (Person)i.next();
sop(p.getName()+"::"+p.getAge());
}
}
}
class Person
{
private String name;
private int age;
Person(String name, int age)
{
this.name = name;
this.age = age;
}
public int hashCode() //两元素比较 hashCode 值,相等再往下比较 equals 。不相等就不用往下进行了,直接返回哈希值。
{
// System.out.println(this.name+".......hashCode"); // 显示如何运行
return name.hashCode();
// return name.hashCode()+age*23;
//返回一个姓名的哈希值再加上年龄,这样做提高了判断的精确度,但为防一个哈希值(20)和年龄(40)的和(60) 与 另一个哈希值(30)和年龄(30)的和(60)相等,就在年龄后面乘上
//个数这样不仅提高了精确度也提高了效率, hashCode 值不相等的不用再进行 equals 比较了。
}
public boolean equals(Object obj) // 来比较 equals 的两个值,hashCode 值必定相同。
{
if(!(obj instanceof Person))
return false;
Person p = (Person)obj; // 向下转型
// System.out.println(this.name+".....equals......"+p.age); // 显示如何运行
return this.name.equals(p.name) && this.age == p.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
LinkedHashSet
1. LinkedHashSet 集合是 HashSet 集合的子类,也是根据 hashCode 值来决定元素存储位置,但它同时使用链表维护元素的次序,当遍历 LinkedHashSet 集合里元素时,HashSet 将会按元素的添加顺序来访问集合里的元素。 LinkedHashSet 的性能略低于 HashSet 的性能。
例4:
import java.util.LinkedHashSet;
class Test
{
public static void main(String[] args)
{
LinkedHashSet books = new LinkedHashSet();
books.add("Java01");
books.add("Java02");
books.add("Java03");
books.add("Java04");
System.out.println(books);
}
}
范例分析: 元素输出顺序与输入顺序一致。