------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
l Set
特点:
1. 无序(存储和查询的顺序不同,因为是按照对象的地址值存储进去的)。
2. 不可重复。
通过查看API,Set的功能与Collection是一样的。
常用子类
1. HashSet
2. TreeSet
l HashSet
HashSet如何保证元素的唯一性?
原理:将对象存储在HashTable中,HashTable是通过该对象自己的HashCode得出地址的。当两个对象的地址相同时,还要判断其内容是否相同(使用equals())方法。
需求:
将自己定义的Person对象存储到HashSet中,重写HashCode()和equals()方法。
代码:
package com.lxh.collection;
public class Person {
private String name;
private int age;
public Person(String name,int age) {
this.name = name;
this.age = age;
}
public String get() {
return name + "::" + age;
}
public int hashCode() {
// return name.hashCode() + age*39;
return 90;
}
public boolean equals(Object obj){
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
System.out.println(this.name + "...equals..." + p.name );
return this.age == p.age && this.name.equals(p.name);
}
}
package com.lxh.collection;
import java.util.*;
public class package com.lxh.collection;
import java.util.*;
public class HashSetDemo {
public static void main(String[] args) {
HashSet hs = new HashSet();
hs.add(new Person("aaa",10));
hs.add(new Person("bbb",12));
hs.add(new Person("ccc",14));
hs.add(new Person("aaa",10));
Iterator it = hs.iterator();
while(it.hasNext()) {
Person p = (Person)it.next();
System.out.println(p.get());
}
}
}
{
public static void main(String[] args) {
HashSet hs = new HashSet();
hs.add(new Person("aaa",10));
hs.add(new Person("bbb",12));
hs.add(new Person("ccc",14));
hs.add(new Person("aaa",10));
Iterator it = hs.iterator();
while(it.hasNext()) {
Person p = (Person)it.next();
System.out.println(p.get());
}
}
}
输出结果:
bbb...equals...aaa
ccc...equals...bbb
ccc...equals...aaa
aaa...equals...ccc
aaa...equals...bbb
aaa...equals...aaa
ccc::14
bbb::12
aaa::10
l TreeSet
两个或两个以上的对象想要加入TreeSet中时,需要实现Comparable<T>接口,此对象可以对元素按照自然排序进行排序。
Comparable<T>接口
此接口强行对实现它的对象进行整体排序,这种排序被称为自然排序,类的compareTo()方法被称之为自然排序方法。
TreeSet如何保证元素的唯一性?
记录的对象实现Comparable<T>接口,通过compareTo()方法进行比较。
常用方法:
int compareTo(T o)
如果该对象<,=或>,则返回负数,零和正数,通常使用 -1,0 ,1。
重写的CompareTo(Object obj)方法,对应一级比较内容相同时,可以比较二级字段。
package com.lxh.collection;
public class Person implements Comparable {
private String name;
private int age;
public Person(String name,int age) {
this.name = name;
this.age = age;
}
public String get() {
return name + "::" + age;
}
public int compareTo(Object obj) {
if(!(obj instanceof Person))
throw new RuntimeException("不是Person对象");
/**
* 直接返回1,是正向排序
* 直接返回-1,是逆向排序
* 直接返回0,只返回第一个对象
* */
// return 1;
Person p = (Person)obj;
if(age < p.age)
return -1;
if(age == p.age) {
return this.name.compareTo(p.name);
}
return 1;
}
}
package com.lxh.collection;
import java.util.*;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add(new Person("001",23));
ts.add(new Person("002",22));
ts.add(new Person("003",24));
ts.add(new Person("004",23));
Iterator it = ts.iterator();
while(it.hasNext()) {
Person p = (Person)it.next();
System.out.println(p.get());
}
}
}
当不能修改实现了Comparable接口的对象的compareTo()方法时,或者compareTo()方法不能够买足需求,可以考虑让集合自身具备比较的性能。通过TreeSet的构造方法来实现:
TreeSet(Comparator<? super E> comparator) |
l Comparator<T>接口
强行对某个对象collection进行整体排序的比较函数。
方法:
compare(Object o1 , Object o2)
如果该第一个对象<,=或>第二个对象,则返回负数,零和正数,通常使用 -1,0 ,1。
需求:
使用比较器让TreeSet对象自身具有比较功能。
思路
使用构造方法TreeSet(Comparator<? super E> comparator),使集合可以去比较添加进来的对象。
创造构造器类,其实现Comparator接口。重写compare(Object o1, Object o2)方法
package com.lxh.collection;
import java.util.*;
public class TreeSetDemo2 {
public static void main(String[] args) {
TreeSet ts = new TreeSet(new Compare());
ts.add(new Person("001",23));
ts.add(new Person("002",22));
ts.add(new Person("004",24));
ts.add(new Person("003",23));
ts.add(new Person("003",29));
Iterator it = ts.iterator();
while(it.hasNext()) {
Person p = (Person)it.next();
System.out.println(p.get());
}
}
}
/**
* 比较器
* */
class Compare implements Comparator {
Person p1 = null;
Person p2 = null;
public int compare(Object o1, Object o2) {
Person p1 = (Person)o1;
Person p2 = (Person)o2;
int num = p1.getName().compareTo(p2.getName());
if(num == 0) {
/*
if(p1.getAge() < p2.getAge())
return -1;
if(p2.getAge() > p2.getAge())
return 1;
return 0;
*/
// 使用Integer类封装int类型的正数。
return (new Integer(p1.getAge()).compareTo(new Integer(p2.getAge())));
}
return num;
}
}
public class Person /*implements Comparable*/ {
private String name;
private int age;
public Person(String name,int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String get() {
return name + "::" + age;
}
}
练习:
按照字符串的长度进行比较排序。
package com.lxh.collection;
import java.util.*;
public class TreeSetCompareString {
/**
* @param args
*/
public static void main(String[] args) {
TreeSet ts = new TreeSet(new StringComparator());
ts.add("sdfsd");
ts.add("s");
ts.add("fasefwefas");
ts.add("sdfsa");
ts.add("sdfsa");
Iterator it = ts.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
class StringComparator implements Comparator {
String s1 = null;
String s2 = null;
public int compare(Object o1,Object o2) {
s1 = (String)o1;
s2 = (String)o2;
// if(s1.length() < s2.length())
// return -1;
// if(s1.length() == s2.length())
// return s1.compareTo(s2);
// return 1;
int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
if(num == 0)
return s1.compareTo(s2);
return num;
}
}