Collection单列集合的体系结构简介

Collection

一、Collection:单列集合
1.简介:

Collection是单列集合的祖宗,每个元素(数据)只包含一个值

2.体系结构:
image-20240914104550400
3.常用方法:所有单列集合都会继承

(1)boolean add(E e)

​ 将指定对象添加到当前集合中

(2)void clear()

​ 清空集合中的所有元素

(3)boolean remove(E e)

​ 将指定对象在当前集合中删除

(4)boolean contains(Object obj)

​ 判断当前集合中是否包含指定对象

(5)boolean isEmpty()

​ 判断当前集合是否为空

(6)int size()

​ 返回当前集合中的元素个数

(7)Object[] toArray()

​ 将集合中的所有元素存储到数组中


4.遍历方式:

a.迭代器

  • 概述:迭代器是遍历集合的专用方式(数组没有迭代器),在Java中迭代器的代表是Iterator

  • Collection获取迭代器的方式

Iterator<E> iterator() 返回集合中的迭代器对象,该迭代器对象默认指向当前集合的第一个元素

  • Iterator迭代器中的常用方法

    • boolean hasNext() 询问当前位置是否有存在,若存在则返回true,否则返回 false
    • E next() 获取当前位置的元素,同时将迭代器对象指向下一个元素
  • 遍历代码演示

    //1.创建一个Collection集合lists
    Collection<String> lists=new ArrayList<>();
    lists.add("zsh");
    lists.add("zjl");
    lists.add("zxj");
    
    //2.使用迭代器进行遍历
    Iterator<String> it=lists.iterator();
    while(it.hasNext()){
        String element=it.next();
        System.out.println(element);
    }
    

b.增强for循环

  • 格式

    for(元素的数据类型 变量名 : 数组/集合){
        ...
    }
    
  • 遍历代码演示

    //1.创建一个Collection集合lists
    Collection<String> lists=new ArrayList<>();
    lists.add("zsh");
    lists.add("zjl");
    lists.add("zxj");
    
    //2.使用增强for循环进行遍历
    for(String str : lists){
        System.out.println(str);
    }
    

c.Lambda表达式(After JDK1.8)

  • 方法

    default void forEach(Consumer<? super T> action)

  • 原代码

    //1.创建一个Collection集合lists
    Collection<String> lists=new ArrayList<>();
    lists.add("zsh");
    lists.add("zjl");
    lists.add("zxj");
    
    //2.使用forEach方法进行遍历
    lists.forEach(new Consumer<String>(){
        @Override
        public void accept(String str){
            System.out.println(str);
        }
    });
    
  • 优化后代码

    //1.创建一个Collection集合lists
    Collection<String> lists=new ArrayList<>();
    lists.add("zsh");
    lists.add("zjl");
    lists.add("zxj");
    
    //2.结合Lambda表达式,使用forEach方法进行遍历
    lists.forEach(str -> {
        System.out.println(str);
    })
    


二、List:添加的元素有序、可重复、有索引
1.List集合的特有方法:

List集合由于支持索引,所以多了很多与索引相关的方法,当然Collection集合的各种功能List也都一一继承了

注意List集合支持使用for循环进行遍历(因为List集合有索引)

  • void add(int index,E element)

    在集合中的指定位置插入指定元素

  • E remove(int index)

    删除指定位置的元素,并返回被删除的元素的内存地址

  • E set(int index,E element)

    修改指定位置的元素,并返回被修改的元素的内存地址

  • E get(int index)

    返回指定位置的元素的内存地址


2.ArrayList:基于数组实现

a.特点

  • 查询速度快(注意:是根据索引查询数据快):查询数据通过地址和索引进行定位,查询任意数据耗时相同
  • 删除效率低:每删除一个数据,都要将后面的数据依次前移
  • 插入效率低:每插入一个数据,都要将后面的数据依次后移;有时候可能还需要对数组进行扩容

b.底层原理

(1)利用无参构造器创建一个ArrayList集合时,会在底层创建一个默认长度为0的数组

(2)添加第一个元素后,底层会创建一个新的长度为10的数组

(3)存满后,数组会扩容1.5倍

(4)若一次性添加多个元素,1.5倍还存放不下,则新建数组的长度以实际为准

c.应用场景

  • 适合:
    • 根据索引查询数据,比如根据随机索引查询数据(高效)
    • 数据量不大
  • 不适合:
    • 数据量大的同时,又要频繁进行增删操作

3.LinkedList:基于双链表实现

a.特点

  • 查询效率低:无论查询哪个数据,都要从头结点开始找
  • 增删效率高
  • 对首尾元素进行CRUD(Create&Read&Update&Delete)即增删改查的效率极高

b.首尾操作的特有方法

  • void addFirst(E e)
  • void addLast(E e)
  • E getFirst()
  • E getLast()
  • E removeFirst()
  • E removeLast()

c.应用场景:可以用来设计队列/栈



三、Set:添加的元素无序、不重复、无索引
1.HashSet:无序、不重复、无索引

a.前置知识

I.哈希值

  • 哈希值是一个int类型的数值,Java中每个对象都有一个哈希值
  • Java中的所有对象都可以调用Object类提供的int hashCode()方法,返回该对象的哈希值
  • 同一个对象多次调用int hashCode()方法,返回的哈希值都是相同的
  • 不同对象的哈希值一般不相同,但也有一定几率会相同(哈希碰撞)

II.哈希表

  • 哈希表是一种CRUD各方面性能都较好的数据结构
  • JDK1.8之前:哈希表=数组+链表
  • JDK1.8之后:哈希表=数组+链表+红黑树

b.底层原理:基于哈希表实现

(1)创建一个默认长度为16的数组,默认加载因子为0.75

(2)使用元素的哈希值对数组的长度求余,从而计算出该元素应存入的数组索引位置

(3)判断该索引位置是否为null,若是则直接存入

(4)若该索引位置不为null,说明该位置已有元素,则调用equals()方法进行比较

  • 若新元素与已有元素的值相等,则放弃存入
  • 若不相等,则将新元素存入数组
    • JDK 1.8之前:新元素取代已有元素的位置,已有元素转而挂在新元素的下方
    • JDK 1.8之后:新元素直接挂在已有元素的下方

(5)JDK 1.8开始,当链表长度超过8且数组长度>=64时,链表会自动转化成红黑树

c.深入理解HashSet集合的去重机制

  • HashSet默认不能对内容一样的两个不同对象进行去重操作
  • 解决方法:重写对象的hashCode()equals()方法(右键–>Generate–>Override Methods

2.LinkedHashSet:有序、不重复、无索引

底层原理

仍然是基于哈希表实现,但是它的每个元素都额外多了一个双链表的机制,用来记录该元素的前后元素的位置,从而实现有序


3.TreeSet:不重复、无索引、可排序(默认升序,按照元素从小到大排序)

a.底层原理:基于红黑树实现排序

b.默认排序规则

  • 对于数值类型(Integer,Double):默认按照数值本身的大小进行升序排序
  • 对于字符串类型(String):默认按照字典顺序进行升序排序(A~Z)
  • 对于自定义类型(如Student对象):无法直接排序

c.自定义排序规则

I.TreeSet存储自定义类型的元素时,必须指定排序规则,有以下2种方式来指定排序规则:

(1)让自定义的类实现Comparable接口,重写里面的compareTo()方法来指定排序规则

(2)通过调用TreeSet的有参构造器,可以设置Comparator对象,用于指定排序规则

public TreeSet(Comparator<? super E> comparator)

II.以上2种方式中,关于返回值的规则如下:

  • 若认为元素1>元素2,返回正整数
  • 若认为元素1<元素2,返回负整数
  • 若认为元素1=元素2,返回0,此时TreeSet认为这两个元素重复,只会保留其中一个元素

III.注意:若类本身有实现Comparable接口,TreeSet同时也自带比较器,默认使用后者

d.代码演示

方式一:

package Collection;

import java.util.Objects;

public class Student implements Comparable<Student>{//必须实现Comparable接口
    private String name;
    private int age;
    private double height;

    public Student() {

    }

    public Student(String name, int age, double height) {
        this.name = name;
        this.age = age;
        this.height = height;
    }

    //重写compareTo方法
    @Override
    public int compareTo(Student o) {
        //按照年龄进行升序排序
        return this.age-o.age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

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

方式二:

package Collection;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class Test {
    public static void main(String[] args) {
        Set<Student> students=new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                //按照身高进行升序排序
                //注意小数作差后的结果并不是一个整数,所以我们要调用Double类的compare方法
                return Double.compare(o1.getHeight(),o2.getHeight());
            }
        });
    }
}

使用Lambda表达式优化上述代码:

package Collection;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class Test {
    public static void main(String[] args) {
        Set<Student> students=new TreeSet<>((o1,o2) ->{
            return Double.compare(o1.getHeight(),o2.getHeight());
        });
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值