Set集合为集类型,集是最简单的一种集合,存放于集合中的对象不按特定方式排序,只是简单的把对象加入集合中,类似于向口袋里放东西。
1. HashSet类
- 由HashSet类实现的Set集合的优点是能够快速定位集合中的元素。
- 由HashSet类实现的Set集合中的对象必须是唯一的,所以需要添加到由HashSet类实现的Set集合中的对象,需要重新实现equals()方法。
由HashSet类实现的Set集合按照哈希码排序,根据对象的哈希码确定对象的存储位置,所有需要添加到由HashSet类实现的Set集合中的对象,还需要重新实现hashCode()方法。从而保证插入集合中的对象能够合理分布在集合中,以便于快速定位集合中的对象。
【例】使用HashSet类。创建一个Person类,该类需要重新实现equals(Object obj)方法和hashCode()方法,以保证对象标识的唯一性和存储分布的合理性。
代码如下:import java.util.Set; import java.util.HashSet; import java.util.Iterator; public class testHashSet { public static void main(String[] args){ Set<Person> hashSet = new HashSet<Person>(); Person person1 = new Person("马先生", 220181); Person person2 = new Person("李先生", 220186); Person person3 = new Person("王小姐", 220193); hashSet.add(person1); hashSet.add(person2); hashSet.add(person3); Iterator<Person> it = hashSet.iterator(); while(it.hasNext()){ Person person = it.next(); System.out.println(person.getName() + " " + person.getId_card()); } } } class Person{ private String name; private long id_card; public Person(String name, long id_card){ this.name = name; this.id_card = id_card; } public String getName(){ return this.name; } public long getId_card(){ return this.id_card; } public void setName(String name){ this.name = name; } public void setId_card(long id_card){ this.id_card = id_card; } public int hashCode(){ final int PRIME = 31; int result = 1; result = result * PRIME + (int)(this.id_card ^ (this.id_card >>> 32)); result = result * PRIME + (int)((this.name == null) ? 0 : name.hashCode()); return result; } public boolean equals(Object obj){ if(this == obj) return true; if(null == obj) return false; if(this.getClass() != obj.getClass()) return false; final Person other = (Person)obj; if(this.id_card != other.id_card) return false; if(null == this.name){ if(null != other.name) return false; }else if(!this.name.equals(other.name)){ return false; } return true; } }
运行截图如下:
如果既想保留HashSet类快速定位集合中对象的优点,又想让集合中的对象按插入的顺序保存,可以通过HashSet类的子类LinkedHashSet实现Set集合。即将Person类中的如下代码:
Set< Person > hashSet = new HashSet< Person >();
替换为如下代码:
Set< Person > hashSet = new LinkedHashSet< Person >();
2. TreeSet类
TreeSet类不仅实现了Set接口,还实现了java.util.SortedSet接口,从而保证了在遍历集合时按照递增的顺序获得对象。
- 如果遍历对象时按照自然顺序递增排列,则由TreeSet类实现的Set集合存入的对象必须实现Comparable接口。
- 如果遍历对象时按照指定比较器递增排列,则由TreeSet类实现的Set集合存入的对象必须实现自定义比较器类。
TreeSet类通过实现java.util.SortedSet接口增加的方法如下:
- comparator():获得对该集合采用的比较器,返回值为comparator类型,如果未采用任何比较器则返回null。
- first():返回在集合中的排序位于第一的对象。
- last():返回在集合中的排序位于最后的对象。
- headSet(E toElement):截取在toElement(不包含)之前的所有对象,重新生成一个Set集合并返回。
- subSet(E fromElement, E toElement):截取在fromElement(包含)之后,toElement(不包含)之前- 的所有对象,重新生成一个Set集合并返回。
- tail(E fromElement):截取在fromElement(包含)之后的所有对象,重新生成一个Set集合并返回。
2.1 按照自然顺序递增排列
【例】使用TreeSet类。创建一个Person类,由TreeSet类实现的Set集合中的对象要求必须实现java.lang.Comparable接口,这里实现的排序方式为按编号升序排列。
代码如下:
import java.util.Set;
import java.util.TreeSet;
import java.util.Iterator;
import java.util.SortedSet;
class Person implements Comparable{
private String name;
private long id_card;
public Person(String name, long id_card){
this.name = name;
this.id_card = id_card;
}
public String getName(){
return this.name;
}
public long getId_card(){
return this.id_card;
}
public void setName(String name){
this.name = name;
}
public void setId_card(long id_card){
this.id_card = id_card;
}
public int compareTo(Object obj){
Person person = (Person)obj;
int result = (this.id_card > person.id_card) ? 1 : (this.id_card == person.id_card ? 0 : -1);
return result;
}
}
public class testTreeSet {
public static void main(String[] args){
TreeSet<Person> treeSet = new TreeSet<Person>();
Person person1 = new Person("马先生", 220181);
Person person2 = new Person("李先生", 220186);
Person person3 = new Person("王小姐", 220193);
Person person4 = new Person("尹先生", 220196);
Person person5 = new Person("王先生", 220175);
treeSet.add(person1);
treeSet.add(person2);
treeSet.add(person3);
treeSet.add(person4);
treeSet.add(person5);
System.out.println("初始化的集合:");
Iterator<Person> it = treeSet.iterator();
while(it.hasNext()){
Person person = it.next();
System.out.println("------ " + person.getName() + " " + person.getId_card());
}
System.out.println("截取前面部分得到的集合:");
//it = treeSet.headSet(person1).iterator();
SortedSet<Person> treeSet1 = treeSet.headSet(person1);
it = treeSet1.iterator();
while(it.hasNext()){
Person person = it.next();
System.out.println("------ " + person.getName() + " " + person.getId_card());
}
System.out.println("截图中间部分得到的集合:");
it = treeSet.subSet(person1, person3).iterator();
while(it.hasNext()){
Person person = it.next();
System.out.println("------ " + person.getName() + " " + person.getId_card());
}
System.out.println("截取最后部分得到的集合:");
it = treeSet.tailSet(person3).iterator();
while(it.hasNext()){
Person person = it.next();
System.out.println("------ " + person.getName() + " " + person.getId_card());
}
}
}
运行截图如下:
2.2 按照指定比较器递增排列
【例】自定义比较器。在使用由TreeSet类实现的Set集合时,通过单独的比较器对集合中的对象进行排序,比较器类既可以作为一个单独的类,也可以作为对应类的内部类,这里以单独类为例。
代码如下:
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
class Person implements Comparable{
private String name;
private long id_card;
public Person(String name, long id_card){
this.name = name;
this.id_card = id_card;
}
public String getName(){
return this.name;
}
public long getId_card(){
return this.id_card;
}
public void setName(String name){
this.name = name;
}
public void setId_card(long id_card){
this.id_card = id_card;
}
public int compareTo(Object obj){
Person person = (Person)obj;
int result = (this.id_card > person.id_card) ? 1 : (this.id_card == person.id_card ? 0 : -1);
return result;
}
}
//user_defined comparator
class PersonComparator implements Comparator{
public static final int NAME = 1;
public static final int ID_CARD = 2;
private int orderByColumn = 1; //default sort by name
public static final boolean ASC = true;
public static final boolean DESC = false;
private boolean orderByMode = true; //default sort by ASC
@Override
public int compare(Object obj1, Object obj2) {
// TODO Auto-generated method stub
int result = 0;
Person person1 = (Person)obj1;
Person person2 = (Person)obj2;
switch(orderByColumn){
case 2:
if(orderByMode)
result = (int)(person1.getId_card() - person2.getId_card());
else
result = (int)(person2.getId_card() - person1.getId_card());
break;
default:
String s1 = person1.getName();
String s2 = person2.getName();
if(orderByMode)
result = s1.compareTo(s2);
else
result = s2.compareTo(s1);
}
return result;
}
public void orderByColumn(int orderByColumn){
this.orderByColumn = orderByColumn;
}
public void orderByMode(boolean orderByMode){
this.orderByMode = orderByMode;
}
}
public class UserDefinedCompraratorTS {
public static void main(String[] args){
Person p1 = new Person("Mr ma", 220181);
Person p2 = new Person("Mr li", 220186);
Person p3 = new Person("Miss wang", 220193);
TreeSet<Person> treeSet = new TreeSet<Person>();
treeSet.add(p1);
treeSet.add(p2);
treeSet.add(p3);
System.out.println("客户化排序前,默认按编号升序排序:");
TreeSet<Person> treeSet2 = new TreeSet<Person>(treeSet);
Iterator<Person> it = treeSet2.iterator();
while(it.hasNext()){
Person person = it.next();
System.out.println("------" + person.getId_card() + " " + person.getName());
}
System.out.println("客户化排序后,按编号降序排序:");
PersonComparator pc3 = new PersonComparator();
pc3.orderByColumn(PersonComparator.ID_CARD);
pc3.orderByMode(PersonComparator.DESC);
TreeSet<Person> treeSet3 = new TreeSet<Person>(pc3);
treeSet3.addAll(treeSet);
it = treeSet3.iterator();
while(it.hasNext()){
Person person = it.next();
System.out.println("------" + person.getId_card() + " " + person.getName());
}
System.out.println("客户化排序后,按姓名升序排序:");
PersonComparator pc4 = new PersonComparator();
pc4.orderByColumn(PersonComparator.NAME);
TreeSet<Person> treeSet4 = new TreeSet<Person>(pc4);
treeSet4.addAll(treeSet);
it = treeSet4.iterator();
while(it.hasNext()){
Person person = it.next();
System.out.println("------" + person.getId_card() + " " + person.getName());
}
}
}
运行截图如下: