Set集合

1、 Set 接口同样继承自 Collection 接口,它没有对 Collection 接口进行功能上的扩充。与 List 集合不同的是, Set集合中的元素无序,并且存入的元素不允许出现重复。 2、 Set 接口主要有两个实现类, 分别是HashSet和TreeSet 。 HashSet 是根据对象的 哈希值 来确定元素在集合中的存储位置,具有高效的存取和查找性能。 TreeSet 则是 以排序二叉树 的方式来存储元素,它可以对集合中的元素进行排序(自然排序,类似于1,11,2,22,3,33)。

HashSet集合

 HashSet是Set接口的一个实现类,它所存储的元素是不可重复的,并且元素的存储是无序的。

当调用HashSet集合的add()方法存入元素时,首先调用被存入元素的hashCode()方法获得对象的哈希值,然后根据对象的哈希值计算出一个存储位置。如果该位置上没有元素,则直接将该元素存入;如果该位置上有元素存在,则调用该元素的equals()方法依次和该位置上的元素进行比较,如果比较结果均为false说明不存在重复元素,就将该元素存入该位置,否则如果有比较结果为true则说明为重复元素,就用该元素覆盖重复的旧元素。

HashSet集合的输出顺序和存入顺序不一致,因为HashSet集合的元素存储是无序的。 重复存入的元素在集合中只出现一次(即相同元素会被覆盖)。

import java.util.*;
import java.math.*;

public class Main {

public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner cin= new Scanner(System.in);
HashSet list = new HashSet();
for(int i = 0; i < 5; i++) {
String s = cin.nextLine();
list.add(s);
}

Iterator it = list.iterator();
while(it.hasNext()) {
Object ob = it.next();
if("宋兆恒".equals(ob)) {
it.remove();
}

}

System.out.println("删除后的元素有:"+list);

while(it.hasNext()) {
Object ob = it.next();
System.out.println(ob);
}


}

}

向HasheSet集合中存入元素时,为保证HasheSet正常工作,要求所存入的对象重写Object类的hashCode()和equals()方法。若存入的元素未重写hashCode()和equals()方法,在集合内部会调用Object类的hashCode()和equals()方法,结果可能错误。

TreeSet集合

1、TreeSet 是 Set 接口的另一个实现类,内部采用排序二叉树来存储元素,可以对元素进行排序。因为要排序,所以要比较元素大小,这就需要 存入的元素实现Comparable接口 ,或者为 TreeSet 集合定义一个 比较器,即实现Comparator接口 。 TreeSet 集合同样不允许重复的元素,和 HashSet 集合不同, TreeSet 集合不是通过 equals() 方法来判断是否为重复元素,而是通 过比较大小来判断,大小相同元素的就认为是重复元素 。 2、当二叉树中存入新元素时,新元素与第 1 个元素 ( 最顶层元素 ) 进行比较。如果小于第 1 个元素就执行左边的分支,继续和该分支的元素进行比较;如果大于第 1 个元素就执行右边的分支,继续和该分支的元素进行比较。如此递归,直到与最后一个元素进行比较时,如果新元素小于最后一个元素就将其放在最后一个元素的左子树上,如果大于最后一个元素就将其放在最后一个元素的右子树上。在新元素和每个结点元素的比较过程中,如果发现新元素是重复元素,就用新元素覆盖旧元素。

假设向集合中存入8个元素,依次为13、8、17、17、1、11、15、25,如果以二叉树来存储,集合中的存储结构会形成一个树状结构。重复的新元素17会把旧的17替换掉。

Set集合(HashSet、TreeSet)_重复元素


3、通过Iterator迭代器遍历TreeSet集合中的字符串元素会

按照字典序形成一个有序序列。这是因为TreeSet集合对输入元素进行大小比较,在内部利用二叉排序树进行排序。此外,重复元素“Helena”在集合中只出现一次。

注意: TreeSet 集合用Iterator迭代器遍历形成的元素序列都是有序序列。


注意:TreeSet集合判断是否是重复元素不是通过equals()方法,而是通过比较大小,大小相同的元素就认为是重复元素,是借助Comparable接口或者Comparator接口。


import java.util.*;
import java.io.*;
import java.math.*;

class MyComparator implements Comparator{
public int compare(Object ob1, Object ob2) {
String str1 = (String)ob1;
String str2 = (String)ob2;
int temp = str1.length() - str2.length();
//System.out.println(temp);
return temp;
}
}

public class Main{

public static void main(String[] args) {

TreeSet tree = new TreeSet(new MyComparator());
tree.add("A");
tree.add("ABC");
tree.add("AB");
tree.add("ABCD");
tree.add("ABCDEG");
tree.add("ABCDE");
Iterator it = tree.iterator();
while(it.hasNext()) {
Object obj = it.next();
System.out.println(obj);
}
/*运行结果是:
A
AB
ABC
ABCD
ABCDE
ABCDEG
*/


}

}
import java.util.*;
import java.io.*;
import java.math.*;

public class Main{

public static void main(String[] args) {

TreeSet set=new TreeSet(new Comparator() { //匿名内部类方法
@Override
public int compare(Object ob1, Object ob2) {
String str1 = (String)ob1;
String str2 = (String)ob2;

return str1.compareToIgnoreCase(str2);
}
});
set.add("andy");
set.add("apple");
set.add("APPLE");
set.add("bill");
set.add("go");
set.add("BNDY");
set.add("orange");
set.add("风斯特鲁夫斯基");
System.out.println(set);
/*运行结果是:
[andy, apple, bill, BNDY, go, orange, 风斯特鲁夫斯基]
*/


}

}