集合框架Collection (List & Set)

1. 数据结构

1.1. 什么是数据结构

数据结构是用来存储数据的结构,而使用特定数据结构,这些存放数据有特定关系

1.2. 常见的数据结构

1. 数组 ---> 查询快,增删改 慢

2.  链表 ---> 查询慢, 增删改 快

3. 队列 ---> 先进先出 

 4. 栈 ---> 先进后出

 5. 树形结构

2. Collection

3. List 接口(可重复,有序的)

3.1. ArryList(底层数组)

  • ArrayList 底层是一个数组,拥有自动扩容机制。所以--> 查询快 增删慢
  • 可重复、有序的 ,默认容量10。

ArrayList 的默认容量 ->10

3.1.1. ArrayList 的构造方法

  1. ArrayList() :构造一个初始容量为 10 的空集合。
  2. ArrayList(Collection<? extends E> c) :用于创建一个ArrayList对象,并将指定集合(Collection类型集合)中的元素添加到该ArrayList中。
  3. ArrayList(int initialCapacity) : 构造具有指定初始容量的空列表。

3.1.2. ArrayList 的常用方法

具体看API

  1. boolean add(E e) :将指定的元素追加到此列表的末尾。
  2. void add(int index, E element) :在此列表中的指定位置插入指定的元素。

  1. E get(int index) :返回此列表中指定位置的元素。

  1. E remove(int index) :删除该列表中指定位置的元素。
  2. boolean remove(Object o) :从列表中删除指定元素的第一个出现(如果存在)。

  1. int size() :返回此列表中的元素数。
  2. void clear() :从列表中删除所有元素。

3.2. LinkList (底层链表)

底层 双向链表结构, 查询慢,增删 快。

链表底层没有 容量

1. 链表 是由多个 节点 合成的。

2. 节点 --> ①数据 ②下一个节点的内存地址 ③ 上一个节点的内存地址

3. previous 为空 该节点为链表的 头,next 为空 该节点为链表的 尾。

4. 通过 链表头,查询链表头。

Node temp = head;

While(temp.next != null ){

temp=temp.next

}

3.3. 遍历

list 接口遍历方式有四种:

  1. for 循环
  2. forech 循环
  3. iterable 迭代器

Iterator iterator = arrayList.iterator(); // 掉方法获取迭代器;collection父类中实现了Iterable接口。

  1. boolean hasNext():判断是否有下一个元素,如果返回true表示有下一个;
  2. Object next():调用一次获得一个元素(每调用一次指针会向后移动一个);注意:所以一个迭代器只能用一次,想要再次使用需要重写获取新的迭代器。
  3. listIterable 是双向迭代器。’List 特有的迭代器

3.3.1. List 为什么能用迭代器?

因为collection中实现了Iterable接口

  • iterable 是单迭代器,‘
  • listIterable 是双向迭代器,是List 特有的迭代器

4. Set(不重复)

Set 集合框架的特点:

  1. 不包含重复元素的集合
  2. 没有带索引的方法,所有不能使用普通的for循环遍历

4.1. Set 如何验证 重复性(**)

  1. 将添加进去的元素通过 equals 和 hashcode 判断是否相等。
  • equals 相等 hashcode一定相等。
  • hashcode 相等 equals 不一定相等。

4.2. HashSet(无序列,不重复)

无序的,无重复的。

哈希值:是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值

4.2.1. HashSet 集合特点

  • 底层数据结构 是 哈希表
  • 对集合的迭代顺序不做任何保证,也就是说不保证 存储和取出的元素顺序一致。
  • 没有带索引的方法,所以不能使用普通 for 循环遍历。
  • 由于是 Set 集合,所以是不能包含重复元素的集合

4.2.2. HashSet 集合添加一个元素的过程

4.3. LinkedHashSet

有序的,无重复的。

4.3.1. LinkedHashSet 集合特点

  • 哈希表 和 链表 实现的set接口,具有可预测的迭代次序。
  • 由 链表保证元素有序,也就是说 元素的存储和取出顺序是一致的。
  • 由 哈希表保证元素唯一,没有重复的元素。

4.4. TreeSet (不可重复,排序)

  • 不可重复,排序
  • TreeSet是一种可排序的、不允许重复元素的集合,底层采用红黑树实现,具有较高的插入、删除和查找效率。
  • 存储的类型必须一致。

cn.ronghuanet._02set.User cannot be cast to java.lang.Comparable

4.4.1. TreeSet 的结构(存储原理分析)

  1. TreeSet 内部是按照大小进行排序的,大小有对象与对象之间比较进行决定的。
  2. 设计TreeSet之前:Java设计了一个接口Comparable接口,其中提供了对象之间比较的方法CompareTo。
  3. TreeSet 会调用对象的 CompareTo 方法,比较对象,所以我们放入的对象需实现Comparable。

String 重写了compareTo

4.5. 自然排序与定制排序(比较器)

4.5.1. 自然排序 comparable

什么是自然排序
  1. 例如:大家排队,按照高矮个排队,那么同学们自己相互之间就能进行对比每个对象具备自我比较判断的能力,称之为自然排序
  2. 此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo方法被称为它的自然比较方法。
  3. 如果一个类实现了Comparable接口,可以认为这个类的对象具有自然排序的能力(本质就是这个对象可以调用比较的方法compareTo)。
案例

类实现 comparable 接口重写 compareTo 方法

public class User implements Comparable{
    private String name;
    private Integer age;
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(name, user.name) &&
        Objects.equals(age, user.age);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public int compareTo(Object o) {
        User user = (User)o;
        if (this.age > user.age){
            return -1;  
        }else if (this.age < user.age){
            return 1;
        }else{
            return this.name.compareTo(user.name);
            //            if (this.name.length()>user.name.length()){
            //                return -1;
            //            }else{
            //                return 1;
            //            }
        }
    }
}
TreeSet treeSet3 = new TreeSet();

treeSet3.add(new User("zs",10));
treeSet3.add(new User("lss",10));
treeSet3.add(new User("zll",13));
treeSet3.add(new User("myyh",42));
treeSet3.add(new User("yyxzz",15));
System.out.println(treeSet3);

4.5.2. 定制排序(比较器)Comparator

什么是定制排序

定制排序,相当于给容器提供了一个裁判:例如操场就是一个容器,那么体育老师就是这个裁判,每个同学进入操场同学们相互之间可以比较谁比较帅,或者不可以比较谁帅都可以,有了老师这个裁判,老师可以负责比较每一位同学。

为什么需要定制排序
  1. 原来的比较规则不符合所有人的使用需求。
  2. 不存在比较规则的对象,无法放入容器,可以给容器提供定制比较器。
定制排序如何实现

Comparator 是一个比较器的接口(标准),必须得有进行比较的方法 :compare(Object o1,Object o2)

案例
/**
 * 定制排序  - 自己去写一个 比较器
 */
public class DogComparator implements Comparator {
    @Override
    public int compare(Object o1, Object o2) {
        Dog dog1 = (Dog)o1;
        Dog dog2 = (Dog)o2;
        if (dog1.age > dog2.age){
            return 1;
        }else if (dog1.age < dog2.age)
            return -1;
        else{
            return dog1.name.compareTo(dog2.name);
        }
    }
}
TreeSet dogTree = new TreeSet(new DogComparator());
dogTree.add(new Dog("zs",10));
dogTree.add(new Dog("lss",10));
dogTree.add(new Dog("zll",13));
dogTree.add(new Dog("myyh",42));
dogTree.add(new Dog("yyxzz",15));
System.out.println(dogTree);

4.5.3. TreeSet排序 判断重复的标准小结

1、如果采用的是自然排序调用对象的compareTo方法,如果返回0 表示相等;

大于且返回正数,升序排列 => 小于且返回负数,升序排列 对应

大于且返回负数,降序排列 => 小于且返回正数,降序排列对应

2、如果使用的定制排序(比较器),调用比较器的方法compare 返回0 表示相等;

大于且返回正数,升序排列 => 小于且返回负数,升序排列 对应

大于且返回负数,降序排列 => 小于且返回正数,降序排列对应

5. 注意:

集合框架中存储的元素全部都是对象,从1.5开始支持自动装箱拆箱,所以基本数据类型也可以直接添加。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值