HashSet:
HashSet中如果有两个对象有相同的哈希值,但是对象的内容不同,则在同一地址上顺延,都存在同一地址,HashSet打印只可以使用Iterator,但是打印出来的结果和存储的顺序未必一致
利用HashSet来存储自定义的对象,如果姓名和性别一致,则视为同一元素。
1: import java.util.*;
2:3: class Person
4: {5: private String name;
6: private int age;7: Person(String name,int age)
8: {9: this.name=name;
10: this.age=age;
11: }12:13: public int hashCode()14: {15: System.out.println(this.name+"...hashCode");16: return 60;
17: }18:19: public boolean equals(Object obj)20: {21: if(!(obj instanceof Person))22: return false;23: Person p=(Person)obj;24: System.out.println(this.name+".....equals..."+p.name);25: return this.name.equals(p.name)&&this.age==p.age;26: }27: }28:29: class HashSetDemo
30: {31: public static void main(String[] args)32: {33: HashSet hs=new HashSet();
34: hs.add(new Person("a1",11));35: hs.add(new Person("a2",12));36: hs.add(new Person("a3",13));37:38: }39: }
HashSet是如何保证元素的唯一性的呢?
是通过元素的两个方面,hashCode和equals来完成的,如果元素的hashCode值相同,才会判断equals是否为true,如果元素的hashCode值不同,则不会调用equals方法。
对于判断元素是否存在,以及删除等操作,依据的方法就是元素的hashCode和equals方法。。
TreeSet:
当主要条件相同时,判断次要条件。
1: import java.util.*;
2:3: class Student implements Comparable//该接口强制让学生具备比较性4: {5: private String name;
6: private int age;7:8: Student(String name,int age)
9: {10: this.name=name;
11: this.age=age;
12: }13:14: public String getName()
15: {16: return name;
17: }18: public int getAge()19: {20: return age;
21: }22:23: //实现Comparable接口
24: public int compareTo(Object obj)25: {26: if(!(obj instanceof Student))27: throw new RuntimeException("不是学生类对象");28: Student s=(Student)obj;29:30: //首先比较年龄,如果年龄相同的话,则比较姓名
31: if(this.age>s.age)32: return 1;
33: else if(this.age==s.age)34: {35: return this.name.compareTo(s.name);36: }37: else return -1;38: }39: }40: class TreeSetDemo
41: {42: public static void main(String[] args)43: {44: TreeSet ts=new TreeSet();
45:46: ts.add(new Student("lisi02",22));47: ts.add(new Student("lisi007",20));48: ts.add(new Student("lisi09",19));49: ts.add(new Student("lisi08",19));50: ts.add(new Student("lisi11",40));51: ts.add(new Student("lisi16",30));52: ts.add(new Student("lisi12",36));53: ts.add(new Student("lisi10",29));54: ts.add(new Student("lisi22",90));55:56: Iterator it=ts.iterator();57: while(it.hasNext())
58: {59: Object obj=it.next();60: Student s=(Student)obj;61: System.out.println(s.getName()+"......."+s.getAge());
62: }63:64: }65: }66:
TreeSet集合的第二种排序方式:
当元素自身不具备比较性时,或者具备的比较性不是所需要的时,这时就需要让集合自身具备比较性。定义一个比较器Comparator,将比较器对象作为参数传递给TreeSet集合的构造函数。如果希望在上述代码的基础上,将TreeSet集合中的对象按照姓名进行排序,当比较器和CompareTo方法均存在时,以比较器为主。
1: class MyCompare implements Comparator2: {3: public int compare(Object o1,Object o2)4: {5: Student s1=(Student)o1;6: Student s2=(Student)o2;7:8: int num=s1.getName().compareTo(s2.getName());
9: if(num==0)
10: return (s1.getAge()-s2.getAge());
11:12: return num;
13: }14:15: }
泛型:
JDK1.5的新特性。用于解决安全问题。是一个安全机制。
ArrayList<String> al=new ArrayList<String> ( );<>中指定该集合存储的类型为String,这就是泛型。
好处:<1>将运行时期出现的问题,ClassCastException,转移到了编译时期,方便程序员解决问题,让运行时期的问题减少,安全
Itetator<String> it=al.iterator( );
<2>避免了强制转换的麻烦。
格式:通过<>来定义要操作的引用数据类型。当使用集合时,将集合中要存储的数据类型作为参数传递给<>中即可。
例如:class LenComparator implements Comparator<String>
泛型类:当类中操作的引用数据类型不确定时,早起定义Object类,现在定义泛型来完成扩展。泛型定义的泛型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。public <T> void (T t),定义泛型方法,该定义只在该方法内有效。
静态方法不可以访问类上定义的泛型,如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。public static <T> void method(T t)
泛型定义在接口上:
1: interface Inter<T>
2: {3: void show(T t);
4: }5:6: class InterImpl implements Inter<String>7: //实现接口时要指定好操作的类型
8:9: class InterImpl<T> implements Inter<T>10: {11: public void show(T t)12: { }13:14: }15: //实现接口时,不指定操作的类型。
泛型限定:当对象的类型不确定时,可以使用通配符来占位<?>
1:2: class GenericDemo6
3: {4: public static void main(String[] args)5: {6: ArrayList<String> al=new ArrayList<String>();
7:8: al.add("abc1");
9: al.add("abc2");
10: al.add("abc3");
11:12: ArrayList<Integer> al1=new ArrayList<Integer>();
13: al1.add(4);14: al1.add(7);15:16: printColl(al);17: printColl(al1);18:19: }20:21: public static void PrintColl(ArrayList<?> al)22: {23: Iterator<?> it=al.iterator();24: while(it.hasNext())
25: {26: System.out.println(it.next());27: }28: }29: /*
30: public static<T> void printColl(ArrayList<T> al)31: 如果写成这样,可以在方法内使用该类的引用,如T t=it.next();32: 如果写成通配符的形式,则不可以使用类型的具体方法33: */34: public static void printColl_1(ArrayList<? extends Person> al)35: {36: Iterator<? extends Person> it=al.iterator();
37: while(it.hasNext())
38: {39: System.out.println(it.next());40: }41:42: }43: /*
44: 泛型的限定:<1>? extends E:可以接收E类型获取E类型的子类型,上限45: <2>? super E:可以接收E类型或者E类型的父类,下限46: */47: }