java集合02:Collection集合,Set子集合,HashSet实现类和TreeSet实现类

Set集合

  1. Set集合

特点: 无序,无下标,元素不可重复
方法:全部继承Collection中的方法

  1. Set集合的方法(全部继承Collection中的方法)
用法解释
boolean add(E e)如果 set 中尚未存在指定的元素,则添加此元素(可选操作)。
boolean addAll(Collection<? extends E> c)如果 set 中没有指定 collection 中的所有元素,则将其添加到此 set 中(可选操作)。
void clear()移除此 set 中的所有元素(可选操作)。
boolean contains(Object o)如果 set 包含指定的元素,则返回 true。
boolean containsAll(Collection<?> c)如果此 set 包含指定 collection 的所有元素,则返回 true。
boolean equals(Object o)比较指定对象与此 set 的相等性。
int hashCode()返回 set 的哈希码值。
boolean isEmpty()如果 set 不包含元素,则返回 true。
Iterator iterator()返回在此 set 中的元素上进行迭代的迭代器。
boolean remove(Object o)如果 set 中存在指定的元素,则将其移除(可选操作)。
boolean removeAll(Collection<?> c)移除 set 中那些包含在指定 collection 中的元素(可选操作)。
boolean retainAll(Collection<?> c)仅保留 set 中那些包含在指定 collection 中的元素(可选操作)。
int size()返回 set 中的元素数(其容量)。
Object[] toArray()返回一个包含 set 中所有元素的数组。
T[] toArray(T[] a)返回一个包含此 set 中所有元素的数组;返回数组的运行时类型是指定数组的类型。
  1. Set接口的使用
public static void main(String[] args) {
        Set set = new HashSet();
        //添加元素,不可重复,无序
        set.add(1);
        set.add(2);
        set.add(3);
        System.out.println("元素个数"+set.size());
        System.out.println(set.toString());
        //删除
        //set.remove(1);
        //set.clear();
        //遍历
        //3.1 增强for
        for (Object O: set
             ) {
           Integer integer =(Integer) O;
            System.out.println(O);
        }
        //3.2使用迭代器
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            Integer i=(Integer) iterator.next();
            System.out.println(i);
        }
        //判断
        System.out.println(set.contains(1));
        System.out.println(set.isEmpty());
    

HashSet

  1. HashSet实现类的特点
  • 基于hashCode计算元素存放位置
  • 当存入元素的hash码相同时,会调用equals方法进行确认,如果返回为true,则拒绝后者进入
  • 存储结构:数组+链表+红黑树
  • HashSet()构造一个新的空 set,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75(加载因子是表示Hsah表中元素的填满的程度,16*0.75=12,容量到了12就开始扩容)。
  1. HashSet的方法
用法解释
boolean add(E e)如果此 set 中尚未包含指定元素,则添加指定元素。
void clear()从此 set 中移除所有元素。
Object clone()返回此 HashSet 实例的浅表副本:并没有复制这些元素本身。
boolean contains(Object o)如果此 set 包含指定元素,则返回 true。
boolean isEmpty()如果此 set 不包含任何元素,则返回 true。
Iterator iterator()返回对此 set 中元素进行迭代的迭代器。
boolean remove(Object o)如果指定元素存在于此 set 中,则将其移除。
int size()返回此 set 中的元素的数量(set 的容量)。
  1. HashSet的使用
  //添加元素
        System.out.println("=============================");
        HashSet<String> hashSet = new HashSet();
         hashSet.add("张三");
        hashSet.add("李四");
        hashSet.add("王五");
        hashSet.add("老六");
        System.out.println("元素个数"+hashSet.size());
        System.out.println(hashSet.toString());
        //删除元素
        System.out.println("=============================");
        hashSet.remove("李四");
        //hashSet.clear();
        //遍历元素
        System.out.println("=============================");
        //3.1增强for
        for (String string:hashSet
             ) {
            System.out.println(string);
        }
        //3.2使用迭代器Iterator
        Iterator iterator = hashSet.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        //判断元素
        System.out.println("=============================");
        System.out.println(hashSet.contains("王五"));
        System.out.println(hashSet.isEmpty());
  1. HashSet的使用2
  HashSet<Student> hashSet = new HashSet();
        //添加元素
        Student s1 =new Student("aaa",15);
        Student s2 =new Student("bbb",16);
        Student s3 =new Student("ccc",17);
        Student s4 =new Student("ccc",17);
        hashSet.add(s1);
        hashSet.add(s2);
        hashSet.add(s3);
        //重复的添加不了
        hashSet.add(s4);
        //存储方式
        //1. 根据hashCode计算保存的位置,如果位置为空则直接保存,如果位置不为空执行第二步
        //2.执行equals方法,如果返回为true则认为存储的元素重复,不能添加,如果为false则形成链表
        hashSet.add(new Student("ddd",20));
        System.out.println("元素个数"+hashSet.size());
        System.out.println(hashSet.toString());
        //删除元素
        hashSet.remove(s3);
        System.out.println("删除之后"+hashSet.size());
        System.out.println(hashSet.toString());
        //3.遍历
        //3.1使用迭代器Iterator
        Iterator iterator =hashSet.iterator();

        while (iterator.hasNext()){
            System.out.println( iterator.next());
        }
        //3.2使用增强for
        for (Student s:hashSet
             ) {
            System.out.println(s);
        }
        //判断
        System.out.println(hashSet.contains(s2));
        System.out.println(hashSet.isEmpty());

Student类中重写的hashCode方法和equals方法

      @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null ) return false;
        if(o instanceof Student) {
            Student student = (Student) o;
           if (this.age == student.age && this.name.equals(student.name))
           {
               return true;
           }
        }

        return false;
    }

    @Override
    public int hashCode() {
       int n1=this.name.hashCode();
       //这里+31是因为31是一个质数(只能被1和自身整除的数),可以减少散列冲突2.31能提高执行效率(31*i=(i<<5)-i)i右移5位就是i乘以2的五次方
       int n2=this.age+31;
       //n1+n2wei 名字和年龄的hashCode编码,有可能名字年龄不一样但是hash编码一样
       return n1+n2;
  1. HashSet的存储结构
    在这里插入图片描述

TreeSet

  1. TreeSet实现类的特点
  • 基于排列顺序来实现元素不重复
  • 实现了SortedSet接口,对集合元素自动排序
  • 元素对象的类型必须实现一个Comparable接口,指定排序规则
  • 通过ComparaTo方法来确定死否位重复元素
  • 存储结构:红黑树(红黑树是一种含有红黑结点并能自平衡的二叉查找树(左节点小于根节点,右节点大于根节点))
  1. TreeSet的方法
boolean add(E e)将指定的元素添加到此 set(如果该元素尚未存在于 set 中)。
boolean addAll(Collection<? extends E> c)将指定 collection 中的所有元素添加到此 set 中。
E ceiling(E e)返回此 set 中大于等于给定元素的最小元素;如果不存在这样的元素,则返回 null。
void clear()移除此 set 中的所有元素。
Object clone()返回 TreeSet 实例的浅表副本。
Comparator<? super E> comparator()返回对此 set 中的元素进行排序的比较器;如果此 set 使用其元素的自然顺序,则返回 null。
boolean contains(Object o)如果此 set 包含指定的元素,则返回 true。
Iterator descendingIterator()返回在此 set 元素上按降序进行迭代的迭代器。
NavigableSet descendingSet()返回此 set 中所包含元素的逆序视图。
E first()返回此 set 中当前第一个(最低)元素。
E floor(E e)返回此 set 中小于等于给定元素的最大元素;如果不存在这样的元素,则返回 null。
SortedSet headSet(E toElement)返回此 set 的部分视图,其元素严格小于 toElement。
NavigableSet headSet(E toElement, boolean inclusive)返回此 set 的部分视图,其元素小于(或等于,如果 inclusive 为 true)toElement。
E higher(E e)返回此 set 中严格大于给定元素的最小元素;如果不存在这样的元素,则返回 null。
boolean isEmpty()如果此 set 不包含任何元素,则返回 true。
Iterator iterator()返回在此 set 中的元素上按升序进行迭代的迭代器。
E last()返回此 set 中当前最后一个(最高)元素。
E lower(E e)返回此 set 中严格小于给定元素的最大元素;如果不存在这样的元素,则返回 null。
E pollFirst()获取并移除第一个(最低)元素;如果此 set 为空,则返回 null。
E pollLast()获取并移除最后一个(最高)元素;如果此 set 为空,则返回 null。
boolean remove(Object o)将指定的元素从 set 中移除(如果该元素存在于此 set 中)。
int size()返回 set 中的元素数(set 的容量)。
NavigableSet subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive)返回此 set 的部分视图,其元素范围从 fromElement 到 toElement。
SortedSet subSet(E fromElement, E toElement)返回此 set 的部分视图,其元素从 fromElement(包括)到 toElement(不包括)。
SortedSet tailSet(E fromElement)返回此 set 的部分视图,其元素大于等于 fromElement。
NavigableSet tailSet(E fromElement, boolean inclusive)返回此 set 的部分视图,其元素大于(或等于,如果 inclusive 为 true)fromElement。
  1. TreeSet的使用
    简单实现
  System.out.println("=============================");
        TreeSet<String> treeSet = new TreeSet();
        treeSet.add("张三");
        treeSet.add("李四");
        treeSet.add("王五");
        treeSet.add("老六");
        System.out.println("元素个数"+treeSet.size());
        System.out.println(treeSet.toString());
        //删除元素
        System.out.println("=============================");
        treeSet.remove("李四");
        //treeSet.clear();
        //遍历元素
        System.out.println("=============================");
        //3.1增强for
        for (String string:treeSet
        ) {
            System.out.println(string);
        }
        //3.2使用迭代器Iterator
        Iterator iterator = treeSet.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        //判断元素
        System.out.println("=============================");
        System.out.println(treeSet.contains("王五"));
        System.out.println(treeSet.isEmpty());
  1. TreeSet的使用2

当我们直接运行下面代码会发现会报出异常
ClassCastException: Gather.Student cannot be cast to java.lang.Comparable

  • 这是因为当我创建Student类的对象作为元素时,我们必须实现Comparable接口,因为TreeSet的存储结构是红黑树,必须满足左节点小于根节点,右节点大于根节点,但是现在程序不知道比较什么,是去比较name,还是去比较age,还是两个都要比,所以我们让添加元素对象的类去实现Comparable接口,重写ComparaTo方法,我们自己定义比较规则相比age还name我们自己定义

  TreeSet<Student> treeSet = new TreeSet();
       //
        Student s1 =new Student("aaa",15);
        Student s2 =new Student("bbb",16);
        Student s3 =new Student("ccc",17);
        treeSet.add(s1);
        treeSet.add(s2);
        treeSet.add(s3);
        System.out.println("元素个数"+treeSet.size());
        System.out.println(treeSet.toString());

所以我们在Student中重写的ComparaTo的代码如下,如果返回值为0则认为是重复元素

public class Student implements Comparable<Student>{
//定义的规则是先比姓名在比年龄
@Override
    public int compareTo(Student o) {
        int n1=this.getName().compareTo(o.getName());
        int n2=this.getAge()-o.getAge();
        return n1==0?n2:n1;
    }

}

此时在运行就会发现,是按照s1 ,s2,s3,s4的顺序排列,s3和s4的名字一样,所以age小的在前面

TreeSet<Student> treeSet = new TreeSet();
       
        Student s1 =new Student("aaa",15);
        Student s2 =new Student("bbb",16);
        Student s3 =new Student("ccc",17);
        Student s4 =new Student("ccc",20);
        treeSet.add(s1);
        treeSet.add(s2);
        treeSet.add(s3);
        treeSet.add(s4);
        System.out.println("元素个数"+treeSet.size());
        System.out.println(treeSet.toString());
  1. TreeSet的使用3,Comparator的使用

Comparator:我们通过实现Comparator接口来自己定制比较规则(比较器),与Comparable相似,Comparable是排序接口,若一个类实现了Comparable接口,就意味着“该类支持排序”。而Comparator是比较器,我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序

public static void main(String[] args) {
 //注意这里使用了匿名内部类,new一个接口
        TreeSet<Student> treeSet= new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
            //这里的规则是先比较 age在比name,所以输出时s2排在最后
                int n1=o1.getAge()-o2.getAge();
                int n2=o1.getName().compareTo(o2.getName());
                return n1==0?n2:n1;
            }
        });
        Student s1 =new Student("aaa",15);
        Student s2 =new Student("bbb",25);
        Student s3 =new Student("ccc",17);
        Student s4 =new Student("ccc",20);
        treeSet.add(s1);
        treeSet.add(s2);
        treeSet.add(s3);
        treeSet.add(s4);
        System.out.println("元素个数"+treeSet.size());
        System.out.println(treeSet.toString());

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值