Set
Set注重独一无二的性质,该体系集合用于存储无序(存入和取出的顺序不一定相同)元素,值不能重复。对象的相等性本质是对象hashCode值(Java是依据对象的内存地址计算出的此序号)判断的,如果想要让两个不同的对象是为相等的,就必须覆盖Object的hashCode方法和equals方法。
HashSet
哈希表边存放的是哈希值。HashSet存储元素的顺序并不是按照存入是的顺序(和List显然不同)而是按照哈希值来存放所以取数据也是按照哈希值取得。元素的哈希值是通过元素的hashcode方法来获取的,HashSet首先判断两个元素的哈希值,如果哈希值一样,接着会比较equals方法,如果equals返回结果为true,HashSet就视为同一个元素。HashSet通过hashCode值来确定元素在内存中的位置。一个hashCode位置上可以存放多个元素。
import java.util.HashSet;
import java.util.Iterator;
public class HashSetTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 创建
HashSet<Integer> hs = new HashSet<Integer>();
// 添加
for (int i = 0; i < 25; i++) {
hs.add(i);
}
// 长度
System.out.println("长度为: "+hs.size());
// 输出
for (Integer i : hs) {
System.out.print(i + " ");
}
System.out.println();
System.out.println("=======================================================================");
// 加入重复值(不存在重复值)
for (int i = 0; i < 5; i++) {
hs.add(i);
}
// 长度
System.out.println("长度为: "+hs.size());
// 输出
for (Integer i : hs) {
System.out.print(i + " ");
}
// 删除
System.out.println();
System.out.println("=======================================================================");
hs.remove(3);
// 输出
for (Integer i : hs) {
System.out.print(i + " ");
}
System.out.println();
//不存在会返回false
System.out.println("删除25: "+hs.remove(25));
//isEmpty()方法
System.out.println("判断是否为空: "+hs.isEmpty());
//是否存在
System.out.println("是否存在: "+hs.contains(20));
//clear()方法
hs.clear();
System.out.println("判断是否为空: "+hs.isEmpty());
//迭代器
for (int i = 0; i < 25; i++) {
hs.add(i);
}
Iterator<Integer> iterator = hs.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next()+" ");
}
System.out.println();
System.out.println("=======================================================================");
}
}
TreeSet
TreeSet()是使用二叉树的原理对新add()的对象按照指定的顺序(升、降序),每增加一个对象都会进行降序,将对象插入的二叉树指定的位置。Integer和String对象都可以进行默认的TreeSet排序,而自定义类的对象是不可以的,自己定义的类必须实现Comparable接口,并且覆写相应的compareTo()函数,才可以正常使用。在覆写compare()函数时,要返回相应的值才能使TreeSet按照一定的规则来排序。比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
import java.util.TreeSet;
public class TreeSetTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 创建
TreeSet<Student> ts = new TreeSet<Student>();
// 添加
ts.add(new Student(1, "A"));
ts.add(new Student(11, "K"));
for (int i = 0; i < 10; i++) {
int id = (int) (Math.random() * 20 + 1);
String name = "" + (char) (int) (Math.random() * 91 + 64);
ts.add(new Student(id, name));
}
// 输出
System.out.println(ts);
// size()
System.out.println("size : " + ts.size());
// isEmpty()
System.out.println("是否为空: " + ts.isEmpty());
// 是否存在 如果此 set 包含指定的元素,则返回 true。
System.out.println(ts.contains(new Student(1, "A")));
System.out.println(ts);
// first:返回此 set 中当前第一个(最低)元素。
System.out.println("first 当前第一个(最低)元: "+ts.first());
// floor:返回此 set 中小于等于给定元素的最大元素;如果不存在这样的元素,则返回 null。
System.out.println("floor 小于等于给定元素的最大元素: "+ts.floor(new Student(1, "A")));
//higher:返回此 set 中严格大于给定元素的最小元素;如果不存在这样的元素,则返回 null。
System.out.println("higher 大于给定元素的最小元素: "+ts.higher(new Student(1, "A")));
// headSet:返回此 set 的部分视图,其元素严格小于 toElement。
System.out.println("headSet 返回此 set 的部分视图: "+ts.headSet(new Student(1, "A")));
//last:返回此 set 中当前最后一个(最高)元素。
System.out.println("last:返回此 set 中当前最后一个(最高)元素: "+ts.last());
//lower:返回此 set 中小于给定元素的最大元素;如果不存在这样的元素,则返回 null。
System.out.println("lower:返回此 set 中小于给定元素的最大元素: "+ts.lower(new Student(1, "A")));
//pollFirst:获取并移除第一个(最低)元素;如果此 set 为空,则返回 null。
System.out.println("pollFirst:获取并移除第一个(最低)元素: "+ts.pollFirst());
//pollLast:获取并移除最后一个(最高)元素;如果此 set 为空,则返回 null。
ts.add(new Student(26, "Z"));
System.out.println("pollLast:获取并移除最后一个(最高)元素: "+ts.pollLast());
// 删除
System.out.println("删除: " + ts.remove(new Student(1, "A")));
// ceiling() 返回此 set 中大于等于给定元素的最小元素;如果不存在这样的元素,则返回 null。
System.out.println(ts.ceiling(new Student(1, "A")));
// comparator() 返回对此 set 中的元素进行排序的比较器;如果此 set 使用其元素的自然顺序,则返回 null。
System.out.println(ts.comparator());
// descendingIterator:返回在此 set 元素上按降序进行迭代的迭代器。
ts.descendingIterator();
System.out.println(ts);
// descendingSet:返回此 set 中所包含元素的逆序视图。
ts.descendingSet();
System.out.println(ts);
//subSet:返回此 set 的部分视图
System.out.println("A-K");
System.out.println(ts.subSet(new Student(1, "A"), new Student(11, "K")));
//tailSet:返回此 set 的部分视图
System.out.println("K");
System.out.println(ts.tailSet(new Student(11, "K")));
// clear()
ts.clear();
System.out.println("是否为空: " + ts.isEmpty());
}
}
class Student implements Comparable<Object> {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Student(int id, String name) {
super();
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + "]";
}
@Override
public int compareTo(Object o) {
// TODO Auto-generated method stub
Student st = (Student) o;
return this.id - st.id;
}
}
LinkedHashSet
对于LinkedHashSet而言,它继承与HashSet、又基于LinkedHashMap来实现的。LinkedHashSet底层使用LinkedHashMap来保存所有元素,它继承与HashSet,其所有的方法操作上又与HashSet相同,因此LinkedHashSet的实现上非常简单,只提供了四个构造方法,并通过传递一个标识参数,调用父类的构造器,地层构造一个LinkedHashMap来实现,在相关操作上与父类hashSet的操作相同,直接调用父类HashSet方法即可。
import java.util.HashSet;
import java.util.LinkedHashSet;
public class LinkedHashSetTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 创建
LinkedHashSet<String> lhs = new LinkedHashSet<String>();
// 添加
for (int i = 65; i < 91; i++) {
String a = "" + (char) i;
lhs.add(a);
}
// 输出
// size
System.out.println(lhs.size());
System.out.println(lhs);
// 添加重复(不添加)
lhs.add("A");
lhs.add("B");
// 输出
// size
System.out.println(lhs.size());
System.out.println(lhs);
//
System.out.println("==================");
diff_Linked_Hash();
}
/*
* linkedHashSet遍历: L0 L1 L2 L3 L4 L5 L6 L7 L8 L9
* hashSet遍历: H8 H9 H0 H1 H2 H3 H4 H5 H6 H7
*/
public static void diff_Linked_Hash() {
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
HashSet<String> hashSet = new HashSet<>();
for (int i = 0; i < 10; i++) {
linkedHashSet.add("L" + i);
hashSet.add("H" + i);
}
System.out.println("linkedHashSet遍历:");
for (String string : linkedHashSet) {
System.out.print(string + " ");
}
System.out.println();
System.out.println("hashSet遍历:");
for (String string : hashSet) {
System.out.print(string + " ");
}
}
}
HashSet、TreeSet、LinkedHashSet比较
- HashSet的输出顺序是不确定的,但是它的速度最快;
- TreeSet输出顺序是升序排列的;
- LinkedHashSet输出顺序是确定的,就是插入时的顺序。
- 三者性能上:HashSet>LinkedHashSet>TreeSet
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.TreeSet;
public class SetTest {
static long startTime = 0;
static long endTime = 0;
static long duration = 0;
final static int count = 10000;
public static void main(String[] args) {
HashSet<Person> hashSet = new HashSet<Person>();
TreeSet<Person> treeSet = new TreeSet<Person>();
LinkedHashSet<Person> linkedSet = new LinkedHashSet<Person>();
HashSet_time(hashSet);
LinkedHashSet_time(linkedSet);
TreeSet_time(treeSet);
}
// LinkedHashSet
public static void LinkedHashSet_time(LinkedHashSet<Person> linkedSet) {
// start time
startTime = System.nanoTime();
for (int i = 0; i < count; i++) {
linkedSet.add(new Person(i));
}
// end time
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("Link: " + duration);
}
// TreeSet
public static void TreeSet_time(TreeSet<Person> treeSet) {
// start time
startTime = System.nanoTime();
for (int i = 0; i < count; i++) {
treeSet.add(new Person(i));
}
// end time
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("Tree: " + duration);
}
// HashSet
public static void HashSet_time(HashSet<Person> hashSet) {
// start time
startTime = System.nanoTime();
for (int i = 0; i < count; i++) {
hashSet.add(new Person(i));
}
// end time
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("Hash: " + duration);
}
}
class Person implements Comparable<Object>{
private String name;
private int age;
public Person(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Object o) {
// TODO Auto-generated method stub
Person person =(Person) o;
return this.age-person.age;
}
}