Java学习笔记——集合(二)

Collection<E>

Set<E>

  1. 不能有重复元素
  2. 允许null值,且只能存储一个
  3. Set接口中定义的方法与Collection接口中定义的方法一样

 HashSet<E>

  1. 是Set接口的一个实现类,不允许重复元素,不保证迭代顺序
  2. 底层是HashMap,在创建HashSet是,同时创建了HashMap,且向HashSet中存储数据时,其实是存储在HashMap的键上
  3. 允许存储null值
  4. 不同步,即不保证线程安全

面试题:HashMap扩容机制


去重原理:

在向HashSet中存储元素时(执行add()时),会调用hashCode()和equals()方法

1 在向HashSet中存储元素时,首先将当前元素hashCode值与内存中已有的hashCode值比较有无与相同的

2 如果没有相同的hashCode值,认为内存中无该元素,允许存入

3 如果有相同的hashCode值,那么此时就会调用当前元素的equals()用于和之前元素的内容比较。如果内容相同,就不允许存入;如果内容不同,就允许存入


演示:

public void test2() {
        HashSet<Student> stus = new HashSet<>();
        Student s1 = new Student(123,"AAA");
        Student s2 = new Student(123,"AAA");
        Student s3 = new Student(124,"BBB");
        Student s4 = new Student(125,"CCC");
        Student s5 = new Student(124,"BBB");
        Student s6 = new Student(125,"CCC");
        System.out.println(stus.add(s1));
        System.out.println(stus.add(s2));
        System.out.println(stus.add(s3));
        System.out.println(stus.add(s4));
        System.out.println(stus.add(s5));
        System.out.println(stus.add(s6));
        System.out.println(stus);
    }

    public void test1() {
        HashSet<String> set = new HashSet<>();
        set.add("世");
        set.add("界");
        set.add("和");
        set.add("平");
        set.add("!");
        System.out.println(set.add("!"));
        for (String s : set) {
            System.out.println(s);
        }
        set.remove("!");
        System.out.println(set);
    }

LinkedHashSet<E>

  1. 是哈希表和链表实现,即有Set集合不重复的特点,也有链表结构元素有序的特点
  2. 不重复,能保证迭代顺序
  3. 方法和HashSet方法一样

演示:

public void test() {
        LinkedHashSet<String> lhs = new LinkedHashSet<>();
        lhs.add("AB");
        lhs.add("CD");
        lhs.add("BC");
        lhs.add("CD");
        lhs.add("DF");
        lhs.add("BC");
        System.out.println(lhs);
    }

TreeSet<E>

  1. 底层是TreeMap
  2. 会将存入的元素进行自然排序 ——》 有序
  3. (自然顺序是指实现了Comparable接口任意一个类,都可以做的自然顺序)
  4. 不能存储重复元素
  5. 不保证线程安全

面试:TreeSet去重排序原理

TreeSet的去重和排序与之前的hashCode()和equals()没有关系

0 向TreeSet中存储的元素,必须是可比较的

  可比较方式1:元素要实现Comparable接口

  可比较方式2:元素要要参与地Comparator比较器接口中

1 当调用add()方法存储参数时,底层会调用参数本身的comparTo()方法(或者compare()方法)将参数与存在参数比较

2 如果是第一个元素,那就存储 ——》 该元素是根节点

3 如果不是第一个元素,那么该元素将从根节点比较,如果比节点大,存入右树杈,如果比节点小,放入左树杈,相等不存储


演示:

public void test() {
        TreeSet<String> ts = new TreeSet<>();
        ts.add("a");
        ts.add("d");
        ts.add("a");
        ts.add("c");
        ts.add("b");
        ts.add("d");
        System.out.println(ts);
        System.out.println(ts.ceiling("c"));
        System.out.println(ts.higher("c"));
        System.out.println(ts.first());
        System.out.println(ts.last());
        ts.pollLast();
        System.out.println(ts);
    }

    public void test1() {
        TreeSet<Student> stus = new TreeSet<>();

        stus.add(new Student(103,"孙三"));
        stus.add(new Student(104,"李四"));
        stus.add(new Student(102,"钱二"));
        stus.add(new Student(101,"赵大"));
        stus.add(new Student(102,"钱二"));
        stus.add(new Student(101,"赵大"));
        System.out.println(stus);
    }
//Student类
public class Student implements Comparable{
    private int no;
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public Student() {

    }

    public Student(int no, String name) {
        this.no = no;
        this.name = name;
    }

    public Student(String name, int no) {
        this.no = no;
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;

        Student student = (Student) o;

        if (no != student.no)
            return false;
        return name.equals(student.name);
    }

    @Override
    public int hashCode() {
        int result = no;
        result = 31 * result + name.hashCode();
        return result;
    }

    @Override
    public String toString() {
        return "Student{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }

    @Override
    public int compareTo(Object o) {
        Student s = (Student)o;
        byte[] bytes1 = (this.name).getBytes();
        byte[] bytes2 = (s.getName()).getBytes();
        int a = bytes1[1] - bytes2[1];
        int b = this.no - s.getNo();
        return a;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值