一 综述
Set集合类似 于数学中的集合,不允许有重复元素。它判断对象是否相等是根据equals方法。Set继承了Collection的方法,没有另外添加方法。经常使用的是HashSet、TreeSet。
1.HashSet :按照hash算法存储元素,因此查找和存取元素性能较高。
(1)HashSet不是线程同步的;
(2)元素顺序是变化的;
(3)元素的值可以是null,但是只能有一个;
(4)判断元素相等不能不仅仅是equals相等,还有hashcode相等。hashcode决定元素的存储位置。
HashSet有个子类LinkedHashSet,使用链表维护集合的次序。因此插入元素的性能低于HashSet,但是迭代元素的性能较高。LinkedHashSet元素的顺序总是于元素的添加顺序一致。如下面代码所示:
HashSet<String> hlSet = new LinkedHashSet<String>();
hlSet.add("a");
hlSet.add("b");
hlSet.add("c");
hlSet.add("d");
//输出:LinkedHashSet---->[a, b, c, d]
System.out.println("LinkedHashSet---->"+hlSet);
HashSet<String> hSet = new HashSet<String>();
hSet.add("a");
hSet.add("b");
hSet.add("c");
hSet.add("d");
//输出:HashSet---->[d, b, c, a]
System.out.println("HashSet---->"+hSet);
2.TreeSet中元素处于排序状态,它提供了几个额外的方法:
修饰符与类型 | 方法与描述 |
---|---|
boolean | add(E e)
Adds the specified element to this set if it is not already present.
|
boolean | addAll(Collection<? extendsE> c)
Adds all of the elements in the specified collection to this set.
|
E | ceiling(E e)
Returns the least element in this set greater than or equal to the given element, or
null if there is no such element.
|
void | clear()
Removes all of the elements from this set.
|
Object | clone()
Returns a shallow copy of this
TreeSet instance.
|
Comparator<? superE> | comparator()
Returns the comparator used to order the elements in this set, or
null if this set uses the
natural ordering of its elements.
|
boolean | contains(Object o)
Returns
true if this set contains the specified element.
|
Iterator<E> | descendingIterator()
Returns an iterator over the elements in this set in descending order.
|
NavigableSet<E> | descendingSet()
Returns a reverse order view of the elements contained in this set.
|
E | first()
Returns the first (lowest) element currently in this set.
|
E | floor(E e)
Returns the greatest element in this set less than or equal to the given element, or
null if there is no such element.
|
SortedSet<E> | headSet(E toElement)
Returns a view of the portion of this set whose elements are strictly less than
toElement.
|
NavigableSet<E> | headSet(E toElement, boolean inclusive)
Returns a view of the portion of this set whose elements are less than (or equal to, if
inclusive is true)
toElement .
|
E | higher(E e)
Returns the least element in this set strictly greater than the given element, or
null if there is no such element.
|
boolean | isEmpty()
Returns
true if this set contains no elements.
|
Iterator<E> | iterator()
Returns an iterator over the elements in this set in ascending order.
|
E | last()
Returns the last (highest) element currently in this set.
|
E | lower(E e)
Returns the greatest element in this set strictly less than the given element, or
null if there is no such element.
|
E | pollFirst()
Retrieves and removes the first (lowest) element, or returns
null if this set is empty.
|
E | pollLast()
Retrieves and removes the last (highest) element, or returns
null if this set is empty.
|
boolean | remove(Object o)
Removes the specified element from this set if it is present.
|
int | size()
Returns the number of elements in this set (its cardinality).
|
NavigableSet<E> | subSet(E fromElement, boolean fromInclusive,E toElement, boolean toInclusive)
Returns a view of the portion of this set whose elements range from
fromElement to
toElement .
|
SortedSet<E> | subSet(E fromElement,E toElement)
Returns a view of the portion of this set whose elements range from
fromElement, inclusive, to
toElement, exclusive.
|
SortedSet<E> | tailSet(E fromElement)
Returns a view of the portion of this set whose elements are greater than or equal to
fromElement.
|
NavigableSet<E> | tailSet(E fromElement, boolean inclusive)
Returns a view of the portion of this set whose elements are greater than (or equal to, if
inclusive is true)
fromElement
|
TreeSet<Integer> tSet = new TreeSet<Integer>();
tSet.add(1);
tSet.add(2);
tSet.add(3);
tSet.add(4);
tSet.add(5);
tSet.add(6);
System.out.println("first----->"+tSet.first()); //first----->1
System.out.println("last----->"+tSet.last()); //last----->6
System.out.println("lower----->"+tSet.lower(5)); //lower----->4
System.out.println("higher----->"+tSet.higher(2)); //higher----->3
System.out.println("subSet----->"+tSet.subSet(2, 5)); //subSet----->[2, 3, 4]
System.out.println("headSet----->"+tSet.headSet(3)); //headSet----->[1, 2]
System.out.println("tailSet----->"+tSet.tailSet(3)); //tailSet----->[3, 4, 5, 6]
//输出:----->6----->5----->4----->3----->2----->1
Iterator<Integer> itDes= tSet.descendingIterator();
while(itDes.hasNext())
{
System.out.print("----->"+itDes.next());
}
System.out.println();
TreeSet支持两种排序
(1)自然排序:调用compareTo方法来比较元素之间的大小。Java的常用类大都实现了Comparable接口,提供了比较大小的方法:
1》BigDecimal、BigInteger及所有数值型类:按照对应的数值大小比较;
2》Character:按照Unicode码值进行比较;
3》Boolean:True大于False;
4》String:按照字符串中的Unicode值比较;
5》Date、Time:后面的日期时间比前面的大。
向TreeSet中插入元素时,只有第一个不需要实现Comparable接口,后面的都需要实现,否则会报ClassCastException。
(2)定制排序:定制排序需要实现Comparable接口,例如逆序。
public class TreeSetTest3 {
public static void main(String[] args) {
Set<String> set = new TreeSet<String>(new MyComparator());
set.add("a");
set.add("b");
set.add("c");
set.add("d");
set.add("e");
set.add("A");
for(Iterator<String> iterator = set.iterator();iterator.hasNext();){
System.out.print(iterator.next()+" "); //输出:<span style="font-size:18px;color:#3366ff;"><strong>e d c b a A
</strong></span>
}
}
}
class MyComparator implements Comparator<String>{
@Override
public int compare(String o1, String o2) {
return o2.compareTo(o1);//降序排列
}
}
自定义类型的排序:
public class TreeSetTest2 {
public static void main(String[] args) {
Set<Person> set = new TreeSet<Person>(new PersonComparator());
Person p1 = new Person(10);
Person p2 = new Person(20);
Person p3 = new Person(30);
Person p4 = new Person(40);
set.add(p1);
set.add(p2);
set.add(p3);
set.add(p4);
for(Iterator<Person> iterator = set.iterator();iterator.hasNext();){
System.out.print(iterator.next().score+" "); //输出:10,20,30,40
}
}
}
class Person{
int score;
public Person(int score){
this.score = score;
}
public String toString(){
return String.valueOf(this.score);
}
}
class PersonComparator implements Comparator<Person>{
@Override
public int compare(Person o1, Person o2) {
return o1.score - o2.score;
}
}
2、HashSet的性能总是要好于TreeSet,因为TreeSet要维护红黑树。HashSet、TreeSet不是线程同步的。