欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【JavaSE_学习笔记】Set接口及其子实现类

程序员文章站 2024-03-16 13:08:10
...

【JavaSE_学习笔记】Set接口及其子实现类

Set接口

无序,元素不可重复
用于存储无序(存入和取出的顺序不一定相同)元素,值不能重复
单列集合的体系图:

集合的体系:
---------| Collection 单列集合的根接口
--------------|  List  如果是实现了List接口的集合类具备的特点: 有序,元素可重复。
------------------| ArrayList    ArrayList的底层是维护了一个Object数组去实现的, 特点: 查询速度快,增删慢。
------------------| LinkedList   底层是使用了链表数据结构实现的,   特点: 查询速度慢, 增删快。   
------------------| Vector (了解)  Vector 的底层也是使用一个Object数组去实现的,但是Vector线程安全的,操作效率低。
--------------|  Set  如果是实现了Set接口的集合类具备的特点: 无序,元素不可重复。
------------------| HashSet   底层是使用了哈希表支持的, 特点: 存取的速度快。     
------------------| TreeSet   底层使用了红黑树,特点:可以对元素进行排序存储

HashSet

HashSet的存储原理:
  往hashSet添加元素的时候,首先会调用元素的hashCode方法得到元素的哈希码值,通过哈希码值就可以算出该元素在哈希表中的存储位置。
  情况1: 如果根据元素的哈希码算出的位置目前没有任何元素存储在该位置上,那么该元素可以直接添加到哈希表中。
  情况2: 如果根据元素的哈希码算出的位置目前已经有其他元素存储在了该位置上,那么还会调用元素的equals方法再与这个位置上的元素再比较一次,如果equals方法返回的是true,则视为重复元素,不允许添加到哈希表中,如果equals方法返回的是false,该元素则允许添加到哈希表中。
举例:

class Person{

    int id;


    String name;


    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "{ 编号:"+ this.id+" 姓名:"+ this.name+"}";
    }

    @Override
    public boolean equals(Object obj) {
        System.out.println("======equals======");
        Person p  = (Person) obj;
        return this.id ==p.id;
    }

    @Override
    public int hashCode() {
        System.out.println("====hashCode========");
        return this.id;
    }

}


public class Demo2 {

    public static void main(String[] args) {
        HashSet set = new HashSet();   //   李: 

        set.add(new Person(110,"来福"));
        set.add(new Person(110,"陈阿福"));   //在现实生活中只要编号一致,则为同一个人。

        set.add(new Person(119,"旺财"));
        set.add(new Person(220,"如花"));
        System.out.println("集合的元素:"+ set);
    }

}

存储原理:
【JavaSE_学习笔记】Set接口及其子实现类

TreeSet

TreeSet注意:
  1.如果往TreeSet添加元素的时候,如果元素本身具备自然顺序的特性,那么treeSet就会按照元素自然顺序的特性进行排序存储;
  2.如果往TreeSet添加元素的时候, 如果元素本身不具备自然顺序的特性, 那么元素所属的类就必须要实现Comparable接口,把元素的比较规则定义在compareTo(T o)方法上;
  Comparable接口下的方法:
  int compareTo(T o)
  返回值:负整数、零或正整数,根据此对象是小于,等于或大于指定对象决定
  TreeSet在添加元素时主动调用compareTo()方法
  TreeSet方法底层是使用了红黑树(二叉树)数据结构实现的,特点是可以对元素进行排序存储
举例:

public class Demo2 {

    public static void main(String[] args) {
        TreeSet tree = new TreeSet();
        tree.add('b');
        tree.add('f');
        tree.add('a');
        tree.add('z');
        System.out.println(tree);//['a','b','f','z']
    }

}

TreeSet存储原理:
  红黑树的规则:左小右大
【JavaSE_学习笔记】Set接口及其子实现类
  如果还有“泽民”,500,会依次compareTo家宝,习总,克强,但不存储,因为视为重复元素
  3.在TreeSet中如果比较的方法返回0,该元素被视为重复元素,不能被添加
  4.往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,而且元素所属的类没有实现Comparable接口,那么在创建TreeSet对象 的时候就必须要传入一个比较器对象
比较器的创建格式:

class 类名   implements  Comparator{

}

举例:

class Emp implements Comparable<Emp> {

    String name;

    int age;

    double salary;

    public Emp(String name, int age, double salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "{ 姓名:"+ this.name+" 年龄:"+ this.age+ " 薪水:"+this.salary+"}";
    }

    /*
     * 元素与元素之间的比较规则定义在COmparaTo方法上。(non-Javadoc)
        返回值:负整数、零或正整数,根据此对象是小于、等于还是大于指定对象。 

     */
    @Override  //  100.52 - 100.32 = 0.2
    public int compareTo(Emp e) {
        return (int)((this.salary-e.salary)*100);
    }
}

//自定义一个比较器类
class AgeComparator implements Comparator<Emp>{

    @Override
    public int compare(Emp o1, Emp o2) {
        return o1.age-o2.age;
    }
}


public class Demo3 {

    public static void main(String[] args) {
        //创建一个比较器对象
        AgeComparator ageComparator = new AgeComparator();

        TreeSet tree = new TreeSet(ageComparator);
        tree.add(new Emp("家宝",68,200));
        tree.add(new Emp("永康",78,100));    
        tree.add(new Emp("习总",58,300));
        tree.add(new Emp("克强",48,500));

        System.out.println(tree);
    }

}

  5.如果元素已经实现了Comparable接口,当创建TreeSet对象时又传入了比较器对象,则比较规则优先使用比较器的。

上一篇: MVP in Android

下一篇: