作者:kuae_617 | 来源:互联网 | 2023-10-14 21:44
一、HashSet
1. 虑重功能特性(HashMap实现)
2. put(key) 如果重复返回false
/**
* Adds the specified element to this set if it is not already present.
* More formally, adds the specified element e to this set if
* this set contains no element e2 such that
* (e==null ? e2==null : e.equals(e2)).
* If this set already contains the element, the call leaves the set
* unchanged and returns false.
*
* @param e element to be added to this set
* @return true if this set did not already contain the specified
* element
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null; // 重复返回false
}
二、TreeSet(有序的,基于TreeMap红黑树实现)
问题1:
如果试图把一个对象添加到TreeSet时,则该对象的类必须实现Comparable接口,否则程序会抛出异常java.lang.ClassCastException。
如下:
public static void main(String[] args) {
TreeSet t1= new TreeSet();
t1.add(new Err());
t1.add(new Err());
//Exception in thread "main" java.lang.ClassCastException:
}
class Err{
}
原因:
TreeSet集合中添加两个Err对象,添加第一个对象时,TreeSet里没有任何元素,所以不会出现任何问题;当添加第二个Err对象时,TreeSet就会调用该对象的compareTo(Object obj)方法与集合中的其他元素进行比较—如果其对应的类没有实现Comparable 接口,则会引发ClassCastException异常。
问题2:
在实现compareTo(Object o)方法时,都需要将被比较对象obj强制类型转换成相同类型,因为只有相同类的两个示例才会比较大小。
当试图把一个大对象添加到TreeSet集合时,TreeSet会调用该对象的compareTo(Object o)方法与集合中的其他元素进行比较—这就要求集合中的其他元素与该元素是同一类的示例,否则抛出ClassCaseException异常。
总之一句话,如果希望TreeSet能够正常运行,TreeSet只能添加同一类型对象。
错误示例:
public static void main(String[] args) {
TreeSet t2 = new TreeSet();
t2.add("hello");
t2.add(1);
//java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
TreeSet判断标准:
TreeSet判断两个对象是否相等的唯一标准是:两个对象通过compareTo(Object o)方法比较是否返回0 —如果通过compareTo(Object o)方法比较返回0,TreeSet则会认为它们相等:否则就认为它们不相等
例子:
import java.util.*;
/*
class Person implements Comparable
{
private String name;
private int age;
public Person(String name, int age)
{
this.name = name;
this.age = age;
}
@Override
public int compareTo(Object o) {
// TODO Auto-generated method stub
if (o instanceof Person == false) return 0;
Person p = (Person)o;
int t = this.name.compareTo(p.name);
if(t != 0)return t;
return this.age - p.age;
}
public String toString(){
return name + ":" + age;
}
}
*/
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return name + ":" + age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
}
class K implements Comparator {
@Override
public int compare(Object a, Object b) {
// TODO Auto-generated method stub
if (a instanceof Person == false || b instanceof Person == false)
return 0;// 因为如果a,b都不是Person类,那么已经超出了该方法判定的范围,我们只能假定其相等,0表示相等
Person p1 = (Person) a;
Person p2 = (Person) b;
int t = p2.getName().compareTo(p2.getName());
if (t != 0) return t;
return p1.getAge() - p2.getAge();
}
}
public class TreeSetTEST {
public static void main(String[] args) {
// Set a = new TreeSet();
Set a = new TreeSet(new K());
a.add(new Person("hao", 10));
a.add(new Person("hao", 20));
a.add(new Person("hao", 30));
a.add(new Person("hao", 10));
a.add(new Person("zhang", 10));
a.add(new Person("zhang", 11));
a.add(new Person("zhang", 20));
a.add(new Person("li", 40));
System.out.println(a);
}
}