集合框架(四)——Collection 子集 ——————Set及其 小弟们!

来源:互联网 发布:《人生》知乎 编辑:程序博客网 时间:2024/06/01 03:57

Set:集:中的方法和Collection一致,只要注意它的子类对象即可。取出元素只能用迭代器。

    HashSet 

    TreeSet

HashSet——底层数据结构是:哈希表,不保证顺序,是不同步的。

哈希表:根据元素的自身特点来确定应该存储到什么位置上。

位置怎么确定呢?哈希算法。

哈希表的由来:提高查询速度。

【哈希表如何保证所存储的元素的唯一性呢?】

当哈希表出现相同成为冲突,这时说明两个元素的位置相同,再次比较一次两个元素的内容。用equals来完成内容的比较。

如果equals返回的是true,视为同一个元素,不存。如果返回是false,视为不同元素,存储。

 

【哈希值内存地址的区别】

哈希值是通过哈希算法算出来的存储位置,如果哈希值相同,再判断equals,否则不存储;

内存地址:是内存中的实际地址。

【如何往哈希表中存储自定义对象?】

必须覆盖hashCode方法,和equals方法。

【当不知道这个对象到底存储到那个容器中去时,该怎么办呢?】

那就将hashCode equals toString全都覆盖。即使不覆盖也会从Object中继承。

 

HashSetDemo.java

 

TreeSet

可以给Set集合中的元素进行指定方式排序,默认情况下使用的是自然顺序。

【什么是自然顺序】

TreeSet排序的方式一:自然排序

元素自身具备的比较性实现了Comparable接口的compareTo方法。

【练习】TreeSetDemo.java

package day0916;import java.util.Iterator;import java.util.TreeSet;public class TreeSetDemo {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stubTreeSet ts = new TreeSet();ts.add("xixi");ts.add("jfkk");ts.add("jdfiew");ts.add("xnncixi");ts.add("wejkllkxi");ts.add("iiweu");for(Iterator it =ts.iterator(); it.hasNext();){System.out.println(it.next());}}}


 

 

TreeSet排序的方式二:TreeSetTest.java比较器排序

如果元素自身不具备比较性或具备的比较性(自然顺序)不是所需要的。这时候只能用第二种方式。

让容器自身具备比较性。容器一初始化,就具备了比较功能。因为容器是在对象构造时完成的。通过构造方法TreeSetComparator)在容器初始化时可以指定一个比较器。需要实现Comparator接口,覆盖compare方法即可。所以这种方式成为比较器排序。

【练习】——TreeSetTest.java


package cn.itcast.api.p1.set.demo;import java.util.Iterator;import java.util.TreeSet;import cn.itcast.api.p2.comparator.ComparatorByName;import cn.itcast.bean.Person;public class TreeSetDemo {/** * @param args */public static void main(String[] args) {/* * TreeSet:可以给其中的元素进行指定方式排序,使用的自然顺序。 * 自然顺序:就是元素自身的具备的比较性实现了Comparable接口的compareTo方法 *  *  */TreeSet ts = new TreeSet(new ComparatorByName());//按照比较器。ts.add(new Person("lisi1",20));ts.add(new Person("lisi7",28));ts.add(new Person("lisi9",22));ts.add(new Person("lisi3",21));ts.add(new Person("lisi5",26));Iterator it = ts.iterator(); //迭代器用于取出TreeSet集合中的元素while(it.hasNext()){System.out.println(it.next().toString());}}}package cn.itcast.api.p2.comparator;import java.util.Comparator;import cn.itcast.bean.Person;/** * 定义了一个根据Person的Name进行比较的比较器。  * @author Administrator * */public class ComparatorByName extends Object implements Comparator {@Overridepublic int compare(Object o1, Object o2) {Person p1 = (Person)o1;Person p2 = (Person)o2;int temp = p1.getName().compareTo(p2.getName());return temp==0?p1.getAge()-p2.getAge():temp;}}
package cn.itcast.bean;/* * 要想让Person对象具备比较大小的功能。 * 就需要对person对象进行功能的扩展。 * 让Person去实现Comparable接口。让Person具备自然顺序。 覆盖compareTo方法。  *  */public class Person implements Comparable {private String name;private int age;public Person() {super();}public Person(String name, int age) {super();this.name = name;this.age = age;}/** * 覆盖Object类中的hashCode方法。建立Person对象自己特点的哈希值算法。 */public int hashCode(){final int NUMBER = 27;return name.hashCode() + age*NUMBER;//*27是为了尽量保证哈希值唯一。}/** * 覆盖Object类中的equals方法,建立Person对象。 * 判断是否相同的依据。 根据Person自身的特点来判断。 */public boolean equals(Object obj){if(!(obj instanceof Person))return false;Person p = (Person)obj;return this.name.equals(p.name) && this.age == p.age;}/** * @return the name */public String getName() {return name;}/** * @param name the name to set */public void setName(String name) {this.name = name;}/** * @return the age */public int getAge() {return age;}/** * @param age the age to set */public void setAge(int age) {this.age = age;}/* (non-Javadoc) * @see java.lang.Object#toString() */@Overridepublic String toString() {return name+":"+age;}@Overridepublic int compareTo(Object o) {/* * 按照Person对象的年龄进行排序。从小到大。 *//* * 进行对象比较的时候,通常,先比较主要条件,如果主要条件相同,在比较次要条件。 * 如果想要按照人的年龄排序,如果年龄相同,在比较一次姓名。 *///麻烦写法。//Person p = (Person)o;//if(this.age>p.age)//return 1;//if(this.age==p.age)//return this.name.compareTo(p.name);//return -1;//技巧性写法。Person p = (Person)o;int temp = this.age - p.age;return temp==0?this.name.compareTo(p.name):temp;}}

【进行对象比较时】

通常,先比较主要条件,如果主要条件相同,再比较次要条件。




原创粉丝点击