Chp16-Set

目录

Collection

特点

Set的存储特点

常用实现类

创建

常用方法

遍历

哈希表的去重原理

使用

 


Collection

是List和Set的父接口, 存放着List和Set的共性内容

特点

  1. 所有集合都由Collection或Map派生

  2. 没有直接实现类

Set的存储特点

无序, 无下标, 元素不可重复

常用实现类

  1. HashSet

    • JDK1.2 底层哈希表(数组+链表)实现 线程不安全,效率高

  2. LinkedHashSet

    • JDK1.2 是HashSet的子类,底层哈希表实现 线程不安全,效率高

  3. TreeSet

    • JDK1.2 是SortedSet的实现类, 底层红黑树实现 线程不安全,效率高

创建

  • 建议使用多态

Set<泛型> 集合名=new 实现类名();

常用方法

  • 所有方法都继承自父接口

遍历

  1. 迭代器遍历

  2. 外遍历

  3. 自遍历

package com.by.test;
​
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.function.Consumer;
​
public class Test1 {
    public static void main(String[] args) {
        Set<Integer> set = new HashSet<>();
        set.add(10);
        set.add(20);
        set.add(30);
        set.add(40);
        set.add(40);
        //迭代器Iterator
        //1. 获取迭代器
        Iterator<Integer> it = set.iterator();
        //2. 操作迭代器
        while (it.hasNext()) {
            System.out.print(it.next()+"  ");
        }
        System.out.println();
        //外遍历forEach
        for (Integer i : set) {
            System.out.print(i+"  ");
        }
        System.out.println();
        //自遍历-匿名内部类
        set.forEach(new Consumer<Integer>() {
            @Override
            public void accept(Integer i) {
                System.out.print(i+"  ");
            }
        });
        System.out.println();
        //自遍历-lambda简化
        set.forEach(i-> System.out.print(i+"  "));
​
    }
}

哈希表的去重原理

  1. 调用元素的hashCode()获取哈希码值

  2. 通过哈希码值%数组长度(16)得到存放下标

  3. 若下标位置未存有元素则直接存放

  4. 存有元素则调用添加元素的equals()与下标位置所有元素进行的比较

  5. 都不相同. 继续链表存放

  6. 有相同, 则舍弃

HashSet获取集合元素时: 按照底层下标的顺序依次获取, 若下标中的链表有多个元素,则全部获取才会进入下一下标

使用

  1. 底层哈希表实现的集合, 在存储自定义类型时, 必须重写hashCode()和equals()才能实现去重

  2. 可以保证元素存入和取出的顺序一致

    • 取元素时是按照节点顺序获取

  3. TreeSet可以对元素进行默认的升序排序

    • 当TreeSet存放自定义类型时, 必须提供排序规则

      1. 实现Comparable接口, 重写compareTo方法

        • 位置: 对谁排序,让谁重写

        • 原理: 让当前对象(this)与参数对象(o)进行比较, 根据比较结果决定是否换位

        • 返回值规则:

          从小到大:
              this的值>o的值, 返回正数
              this的值<o的值, 返回负数
          从大到小:
              this的值>o的值, 返回负数
              this的值<o的值, 返回正数
          相等返回0
        package com.by.entity;
        ​
        public class Student implements Comparable<Student>{
            private String name;
            private int age;
            private double score;
            //省略构造,getter,setter,toString
            @Override
            public int compareTo(Student o) {
                //根据年龄从大到小排序
                return o.age - this.age;
            }
        }
      2. 实现Comparator,重写compare方法

        • 位置: 为集合声明规则, 将实现类对象写在集合创建处的小括号内

        • 原理: 让方法中的两个参数进行比较,根据比较结果决定是否换位

        Set<Student> set = new TreeSet<>(new Comparator<Student>() {
                    @Override
                    public int compare(Student o1, Student o2) {
                        //根据学生年龄从小到大排序
                        return o1.getAge() - o2.getAge();
                    }
                });
        //lambda简化:
        Set<Student> set = new TreeSet<>((o1, o2) -> o1.getAge() - o2.getAge());

      更推荐使用Comparator:

      1. Comparator优先级更高

      2. 不会破坏类的单一职责

      3. 不会将排序规则与类进行绑定, 可以为不同需求的集合提供不同的排序规则

      4. 有方便阅读和维护

      默认识别的是Comparable

  4. TreeSet的去重规则: 当返回值为0时去重

    • 如果去重和排序需要兼顾, 可以在返回值为0时判断其他属性值是否相同

      Set<Student> set = new TreeSet<>(((o1, o2) -> {
                  //根据成绩从高到低
                  if (o1.getScore() > o2.getScore()) {
                      return -1;
                  } else if (o1.getScore() < o2.getScore()) {
                      return 1;
                  } else {
                      //判断姓名与年龄是否也一致
                      if (o1.getName().equals(o2.getName()) && o1.getAge() == o2.getAge()
                      ) {
                          return 0;//全都一致,证明相同,可去重
                      } else {
                          return -1;//有不一致,证明不同, 任意返回正负,避开0即可
                      }
                  }
              }));
  • 17
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值