集合2-Set集合
Set集合的功能和Collection是一致的。
|--Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复。、
|--HashSet:底层数据结构是哈希表。是线程不安全的。不同步。
HashSet是如何保证元素唯一性的呢?
是通过元素的两个方法,hashCode和equals来完成。
如果元素的HashCode值相同,才会判断equals是否为true。
如果元素的hashcode值不同,不会调用equals。
注意,对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcode和equals方法。
|--TreeSet:可以对set集合中的元素进行排序。
底层数据结构是二叉树。
保证元素唯一性的依据:
compareTo方法相同return 0.
TreeSet排序的第一种方式:让元素自身具备比较性。
元素需要实现Comparable接口,覆盖compareTo方法。
也种方式也成为元素的自然顺序,或者叫做默认顺序。
TreeSet的第二种排序方式。
当元素自身不具备比较性时,或者具备的比较性不是所需要的。
这时就需要让集合自身具备比较性。
在集合初始化时,就有了比较方式。
- import java.util.*;
- class HashSetDemo
- {
- public static void sop(Object obj)
- {
- System.out.println(obj);
- }
- public static void main(String[] args)
- {
- HashSet hs = new HashSet();//创建set集合
- sop(hs.add("java01"));//在集合中添加元素
- sop(hs.add("java01"));
- hs.add("java02");
- hs.add("java03");
- hs.add("java03");
- hs.add("java04");
- Iterator it = hs.iterator();//使用迭代器对集合元素进行获取
- while(it.hasNext())
- {
- sop(it.next());
- }
- }
- }
往hashSet集合中存入自定对象
姓名和年龄相同为同一个人,重复元素。
- import java.util.*;
- class HashSetTest
- {
- public static void sop(Object obj)
- {
- System.out.println(obj);
- }
- public static void main(String[] args)
- {
- HashSet hs = new HashSet();//创建一个集合
- hs.add(new Person("a1",11));//在集合中添加若干元素
- hs.add(new Person("a2",12));
- hs.add(new Person("a3",13));
- hs.add(new Person("a2",12));
- hs.add(new Person("a4",14));
- //sop("a1:"+hs.contains(new Person("a2",12)));
- hs.remove(new Person("a4",13));
- Iterator it = hs.iterator();//获取迭代器
- while(it.hasNext())
- {
- Person p = (Person)it.next();//因为要使用集合中元素的特有方法,要进行强转
- sop(p.getName()+"::"+p.getAge());//打印元素的属性
- }
- }
- }
- class Person//创建一个person类
- {
- private String name;//类中有若干成员属性
- private int age;
- Person(String name,int age)
- {
- this.name = name;
- this.age = age;
- }
- //因存入到hashset中,所以覆盖hashcode和equals方法
- public int hashCode()
- {
- System.out.println(this.name+"....hashCode");
- return name.hashCode()+age*37;//哈希值根据姓名和年龄计算
- }
- 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.name.equals(p.name) && this.age == p.age;//如果姓名和年龄相同,视为同一个人
- }
- //定义获取属性的方法
- public String getName()
- {
- return name;
- }
- public int getAge()
- {
- return age;
- }
- }
Treeset:
需求:
往TreeSet集合中存储自定义对象学生。
想按照学生的年龄进行排序。
记住,排序时,当主要条件相同时,一定判断一下次要条件。
当元素自身不具备比较性,或者具备的比较性不是所需要的。
这时需要让容器自身具备比较性。
定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
当两种排序都存在时,以比较器为主。
定义一个类,实现Comparator接口,覆盖compare方法。
- class TreeSetDemo
- {
- public static void main(String[] args)
- {
- TreeSet ts = new TreeSet();//创建一个treeSet集合
- ts.add(new Student("lisi02",22));//在集合中添加若干元素
- ts.add(new Student("lisi007",20));
- ts.add(new Student("lisi09",19));
- ts.add(new Student("lisi08",19));
- //ts.add(new Student("lisi007",20));
- //ts.add(new Student("lisi01",40));
- Iterator it = ts.iterator();//获取迭代器
- while(it.hasNext())
- {
- Student stu = (Student)it.next();//强转
- System.out.println(stu.getName()+"..."+stu.getAge());//获取元素的成员属性
- }
- }
- }
- class Student implements Comparable//该接口强制让学生具备比较性。
- {
- private String name;
- private int age;
- Student(String name,int age)
- {
- this.name = name;
- this.age = age;
- }
- //覆盖compareTo方法,是该类具有一定的比较规则
- public int compareTo(Object obj)
- {
- if(!(obj instanceof Student))//判断比较的是否是同类对象
- throw new RuntimeException("不是学生对象");
- Student s = (Student)obj;
- System.out.println(this.name+"....compareto....."+s.name);
- if(this.age>s.age)//比较年龄
- return 1;
- if(this.age==s.age)
- {
- return this.name.compareTo(s.name);//如果年龄相同按照姓名排序
- }
- return -1;
- /**/
- }
- public String getName()
- {
- return name;
- }
- public int getAge()
- {
- return age;
- }
- }