集合框架的简要介绍

2023-11-10

目录

集合和数组的区别

Collection接口

ArrayList实现类

ArrayList的创建和使用 

linkedList

Set接口及其实现类

Set接口特点

 HashSet实现类

HashSet特点:

HashSet避免对象重复的规则:

迭代器Iterator 

TreeSet

TreesSet特点:

TreeSet对元素进行排序的方式:

Map接口及其实现类

 HashMap实现类


集合就是用于存储对象的容器。 只要是对象类型就可以存进集合框架中。集合的长度是可变的。 集合中不可以存储基本数据类型的值 。

集合和数组的区别

数组和集合相比,数组的长度是固定的,没有办法动态扩展。二集合存储数据时是没有长度限制的,可以动态扩展。集合容器因为内部的数据结构不同,有多种不同的容器对象。这些容器对象不断的向上抽取,就形成了集合框架。

Collection接口

Collection接口是单值集合的顶层接口,继承关系如下

返回类型

方法名称

描述

boolean

add(Object o)

在集合末尾添加元素

int

size()

返回集合列表中元素个数

boolean

removeAll(Collection col)

删除集合中的所有元素

boolean

contains(Object o)

判断集合中是否存在指定的元素

boolean

remove(Object o)

从集合中删除元素

void

clear()

清除集合中的所有元素

Iterator

iterator()

为Iterator接口实列化

List接口及其实现类

1、特点

  • list集合是有序集合:数据的添加和存储次序一致
  • list集合可以存储重复的数据
  • list集合中的数据可以通过下标访问

ArrayList实现类

特点:

  • 实现了list接口
  • 可以动态扩容,底层自动扩容
  • 通过下标可以快速访问数据
  • 查找快,插入删除慢
  • ArrayList底层是数组,对数组做了封装
  • 可以存储任意类型的数据,包括null
  • 数据按照存储次序排列
  • 数据可以重复
  • 多线程访问时不安全

ArrayList的创建和使用 

//创建一个集合对象  若没有指定集合容器的长度,默认为10
        List list = new ArrayList();
        //添加元素
        list.add("aas");
        list.add("artrgh");
        list.add("agfdg");
        list.add("sdfd");
        list.add("你好");

        List list1 = new ArrayList();
        //将集合list中的元素都添加到集合list1中
        list1.addAll(list);
        System.out.println(list1);
        //修改元素
        list.set(2,"你好");
        System.out.println(list);

        //删除元素
        //元素内容删除,若有重复数据,只删除第一个
//        list.remove("你好");
//        System.out.println(list);

         //下标删除
//        list.remove(2);
//        System.out.println(list);

        //查找
        //元素查找,找到元素的下标
        int a = list.indexOf("你好");
        System.out.println("你好的下标是:"+a);
        //下标查找,得到元素
        Object adss = list.get(1);
        System.out.println(adss);

        //获取集合中元素的个数
        int as = list.size();
        System.out.println(as);

        //判断某元素是否在集合中
        boolean fa = list.contains("你好");
        System.out.println(fa);

        //for循环
        for (Object asd:list
             ) {
            System.out.println(asd);
}

linkedList

LinkedList: 具有List的特征,底层以链表结构实现,可以进行头尾元素的添加删除 

//添加元素
LinkedList list = new LinkedList();
list.add("aas");
list.add("artrgh");
list.add("agfdg");
list.add("sdfd");
//首尾添加
list.addFirst("你好啊");
list.addLast("你好");
System.out.println(list);
//首尾删除
list.removeFirst();
list.removeLast();
System.out.println(list);

//查询操作
int size = list.size();//集合长度
boolean empty = list.isEmpty();//是否为空
Object first = list.getFirst();//获取第一个元素
Object last = list.getLast();//获取最后一个元素
System.out.println(first);
System.out.println(last);

Set接口及其实现类

Set接口特点

  • Set接口是无序的
  • Set接口中的数据不允许重复
  • Set接口无法通过下标访问数据
  • 查找慢,插入删除快(底层数据结构是哈希表和红黑树)
  • Set集合使用equals()和hashCode()方法实现元素去重

 HashSet实现类

HashSet特点:

  • HashSet是Set接口的实现类
  • 线程不安全
 //如果没有指定容器大小,默认为16,负载因子为0.75
        HashSet hashSet = new HashSet();
        //添加元素
        hashSet.add("dfsdf");
        hashSet.add("sdfgsdg");
        hashSet.add("sdfette");
        System.out.println(hashSet);
          //删除元素
        hashSet.remove("dfsdf");
        System.out.println(hashSet);
        //清空集合元素
//        hashSet.clear();
//        System.out.println(hashSet);
        boolean dfs= hashSet.isEmpty();//判断容器是否为空
        boolean sdf = hashSet.contains("dfsdf");//判断是否包含某元素
        System.out.println(dfs+" "+sdf);

        //迭代器遍历
        Iterator iterator = hashSet.iterator();//获取迭代对象,有序:由下标
        while(iterator.hasNext()){//判断指针是否可以指定移动
            System.out.println(iterator.next());

HashSet避免对象重复的规则:

1)如果对象的hashCode值不同,则不用判断equals方法,就直接存到HashSet中。

2)如果对象的hashCode值相同,需要用equals方法进行比较,如果结果为true,则视为相同元素,不存储。如果结果为false,视为不同元素,进行存储。

迭代器Iterator 

迭代器(iterator)有时又称游标(cursor)是程序设计的软件设计模式,可在容器对象(container,例如链表或数组)上遍访的接口,设计人员无需关心容器对象的内存分配的实现细节。

HashSet类中没有提供根据集合索引获取索引对应的值的⽅法,因此遍历HashSet时需要使⽤Iterator迭代器。Iterator的主要⽅法如下

返回类型

方法

描述

boolean

hasNext()

如果有元素可迭代

Object

next()

返回迭代的下⼀个元素

TreeSet

TreeSet 基于TreeMap 实现。TreeSet可以实现有序集合,但是有序性需要通过比较器实现。

TreesSet特点:

  • 有序
  • 不重复
  • 添加、删除、判断元素存在性效率比较高
  • 线程不安全

TreeSet对元素进行排序的方式:

1) 如果是基本数据类型和String类型,无需其它操作,可以直接进行排序。

2) 对象类型元素排序,需要实现Comparable接口,并覆盖其compareTo方法。

3) 自己定义实现了Comparator接口的排序类,并将其传给TreeSet,实现自定义的排序规则。

Map接口及其实现类

Map接口特点:

  • 以键值对方式存储数据(Collection是单值集合)
  • 键不能重复,键重复时,后面的数据会覆盖前面的数据
  • 可以存储null
  • 键值对数据无序

 

返回类型

方法

描述

Object

get(Object key)

根据key取得value

Object

put(Obejct k,Object v)

向集合中加入元素

void

clear()

清除Map集合

boolean

isEmpty()

判断集合是否为空

boolean

containsKey(Object object)

判断指定的key是否存在

boolean

containsValue(Object value)

判断指定的value是否存在

Set

keySet()

Map中所有的key的集合

Object

remove(Object key)

根据key删除对应的value

Collection

values()

取出全部的value

int

size()

获得集合的长度

 HashMap实现类

HashMap实现了Map接口,拥有Map接口的基本特点。HashMap线程不安全,效率高。HashMap的底层是由哈希表、链表加红黑树构成的。

public class Test01 {
    public static void main(String[] args) {
        TreeSet t1 = new TreeSet();//TreeSet不允许重复元素
        t1.add(new student("孙猴子",18));
        t1.add(new student("猪八戒",52));
        t1.add(new student("沙僧",52));
        t1.add(new student("唐僧",12));
        System.out.println(t1);
    }

}
class student implements Comparable{


    private String name;
    private int age;

    public student(String name, int age) {
        this.name = name;
        this.age = 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;
    }
    //排序:返回结果如果大于0,表示当前元素比o大,如果返回-1,表示当前元素比o小,返回0,表示相同元素
    @Override
    public int compareTo(Object o) {
        student s1 = (student)o;
        System.out.println(this+"-----------------------"+o);
        if (this.age>s1.age){
            return 1;
        }
       if (this.age<s1.age){
           return -1;
       }
       return 0;
    }

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

HashMap底层原理

HashMap的put()和get()的实现

1) map.put(key,value)实现原理

第一步:首先将k,v封装到Node对象当中(节点)。

第二步:它的底层会调用K的hashCode()方法得出hash值。

第三步:通过哈希表函数/哈希算法,将hash值转换成数组的下标,下标位置上如果没有任何元素,就把Node添加到这个位置上。如果说下标对应的位置上有链表。此时,就会拿着k和链表上每个节点的k进行equals。如果所有的equals方法返回都是false,那么这个新的节点将被添加到链表的末尾。如其中有一个equals返回了true,那么这个节点的value将会被覆盖。

2) map.get(key) 实现原理

第一步:先调用k的hashCode()方法得出哈希值,并通过哈希算法转换成数组的下标。

第二步:通过上一步哈希算法转换成数组的下标之后,在通过数组下标快速定位到某个位置上。重点理解如果这个位置上什么都没有,则返回null。如果这个位置上有单向链表,那么它就会拿着参数K和单向链表上的每一个节点的K进行equals,如果所有equals方法都返回false,则get方法返回null。如果其中一个节点的K和参数K进行equals返回true,那么此时该节点的value就是我们要找的value了,get方法最终返回这个要找的value。

Hashtable

Hashtable也实现了Map接口,但是与HashMap相比有如下特点:

  • 以键值对方式存储数据
  • 键不能重复
  • 数据无序
  • 键和值都不能存储null
  • 线程安全,效率低
    Hashtable hashtable =new Hashtable();
    hashtable.put("aaa",100);
    //hashtable.put("aaa",null);
    hashtable.put(null,100);
    hashtable.put("xxx",100);
    System.out.println(hashtable);

    泛型

    泛型:对要管理的数据进行类型限定,方便数据的处理。

    为什么实用泛型:

    在往集合中存储数据的时候缺乏类型检查,不安全

    泛型:类型检查机制;

    好处:省略了装箱和拆箱,效率高;类型安全。

  • 泛型类:针对类中的属性限定类型。在具体使用的时候设置类

  public static void main(String[] args) {
        List<String> list = new ArrayList<>();//这里限制了集合元素的类型,ArrayList后面 的<>在jdk1.8后可以省略,也可不写限制类型
        list.add("sadfg");
        list.add("孙悟空");
        String s1 = list.get(0);//在获取元素时,默认就是相应的数据类型,而无需进行强制转换

        //<k,v>:K:表示键的泛型, v:表示值的泛型
        HashMap<String,Integer> hashMap = new HashMap<>();
        hashMap.put("年龄",18);
    }

 自定义链表

 链表是最简单的动态数据结构,数据存储在节点(Node)中,其节点的数据结构如下:

class Node{ 
   E e;//数据存储的地方   
 Node next;//也是一个节点,他指向当前节点的下一个节点
}

我们可以把链表理解成为一个火车,每个链表,其实就是一节车厢,数据存储在车厢中中,而每个火车节都有一个指针,连接着下一个火车节。

链表有一个优点:

真正的动态数据结构,无需关系创建的空间是否过大,不需要像数据一样担心容量的问题。

缺点:

不能像数组那样,给一个索引就能查找到指定的值。

1.单向链表

单向链表就是通过每个结点的指针指向下一个结点从而链接起来的结构,最后一个节点的next指向null。

 

 

2.单向循环链表

单向循环链表和单向列表的不同是,最后一个节点的next不是指向null,而是指向head节点,形成一个“环”。

.双向链表

从名字就可以看出,双向链表是包含两个指针的,pre指向前一个节点,next指向后一个节点,但是第一个节点head的pre指向null,最后一个节点的tail指向null。

 

.双向循环链表

双向循环链表和双向链表的不同在于,第一个节点的pre指向最后一个节点,最后一个节点的next指向第一个节点,也形成一个“环”。而LinkedList就是基于双向循环链表设计的。

 

集合使用总结:

1) 需要数据唯一时,使用Set集合

  • 需要保持规则顺序,此时用TreeSet
  • 不需要指定顺序,此时用HashSet
  • 需要保证代码添加数据的次序,此时用LinkedHashSet

2) 不需要唯一时,使用List集合

  • 需要频繁增删操作时,使用LinkedList
  • 不需要频繁增删操作,需要做大量查询操作时,使用ArrayList

3) 如果以键值对方式存储数据时,使用HashMap

4) 通过类名记住集合框架类的结构和所属体系

List: ArrayList LinkedList

Set : HashSet TreeSet

后缀名就是该集合所属的体系。 前缀名就是该集合所属的数据结构。

看到array:想到的就是数组,查询速度快。因为有角标是连续的内存地址。

看到link:想到的就是链表,增删动作的速度快,而且要想到

add get remove+first/last的 方法

看到hash:想到的就是哈希表,那么就具有唯一性,

而且要想到元素需要覆盖hashcode方法 和equals方法

看到tree:想到的就是二叉树,接下来想到的就是排序,然后就是两个接口

Comparable接口 实现compareTo(To)

Comparator接口 实现compare() 方法

 

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

集合框架的简要介绍 的相关文章

随机推荐

  • 【CTF\Crypto】聪明的小羊

    聪明的小羊 题目 解题思路 在线的解密工具 离线的解密工具 心得 题目链接 题目 一只小羊翻过了2个栅栏 fa fe13f590lg6d46d0d0 解题思路 观察题目中的关键信息 2个栅栏 所以我们怀疑题目可能是个栅栏密码 我们看见题目中
  • unity 调用android的activity,Unity调用Android的Activity

    写了关于Unity与Android结合所遇到的问题及解决方法 总结一下 Unity做一个简单的场景 AndroidStudio建一个简单的项目 其中MainActivity是要继承自 UnityPlayerActivity的 这样Unity
  • python学习(5):celery-beat-task异步驱动框架

    https github com celery celery tree master examples celery的example程序periodic tasks存在如下问题 2017 08 26 21 52 11 412 INFO Ma
  • 开发中遇到的问题

    1 当写一个导出功能时 因为编码写URL地址 参数的时候 用反转字符串的时候换行了 造成地址拼接不成 一直报错 后来发现是编码格式造成的 已解决 解决方案 不换行或者用 拼接 2 当本地项目起两个终端的时候 会有两个地址 如http loc
  • CSS !important 规则

    CSS important 规则 那么什么是 important呢 CSS中的 important 规则用于向属性 值添加比正常值更重要的内容 事实上 如果你用 important 规则 它将覆盖该元素上该特定属性的所有以前的样式设置规则
  • 利用Matlab实现贝叶斯优化卷积神经网络进行数据回归预测

    利用Matlab实现贝叶斯优化卷积神经网络进行数据回归预测 概述 数据回归预测是一项重要的任务 可以通过建立卷积神经网络 Convolutional Neural Network CNN 来实现 然而 在模型参数调优方面存在着挑战 为了解决
  • http请求参数编码问题

    给某api发送http请求 结果查不到数据 而api开发者自测可以查到数据 僵持不下 经过分析发现 我的url是经过urlencode编码的 传出去的中文变成 E5 B2这种 而api开发者的url是明文传输中文 我通过httpclient
  • 构造原生单选或者多选下拉框

    function getRadioList tag pageNum pageSize ajaxHelper ajaxFun type post url data data contentType application json async
  • 急速安装git lfs

    什么是git LFS LFS是large File Storage的缩写 专门用来帮助git管理大型文件 一 curl s https packagecloud io install repositories github git lfs
  • 【问题解决】eclipse ‘Launching Hello'has encountered a problem

    问题 删除eclipse很多项目后 再次运行某一个项目 就会出现错误 eclipse Launching Hello has encountered a problem 解决方案 点此启动此项目 即可 原因 看网上答案 原来点 run 时是
  • 3D 智慧农场可视化——解锁绿色生态田园

    何为 无人农场 中国工程院院士罗锡文用五句话高度概括 耕种管收生产环节全覆盖 机库田间转移作业全自动 自动避障异况停车保安全 作物生产过程实施全监控 智能决策精准作业全无人 随着新一代信息技术飞速融入传统产业 农业数字化 网络化 智能化逐步
  • 聊天室--javaWeb

    文章目录 一 简介 项目说明 实现的主要功能 系统架构 二 项目代码和demo地址 项目代码 项目demo地址 三 具体的功能实现 登录功能 单点登录 聊天功能的实现 踢人功能 简单的分权限 四 补充说明 关于代码 关于项目部署 一 简介
  • 方舟官方服务器怎么显示血量,方舟端游怎么显示血量

    解决方舟如何显示伤害数字 在ARK ShooterGame Saved Config WindowsNoEditor文件夹下的GameUserSetting文件的 ServerSettings 的最后一行中添加命令 ShowFloating
  • array_filter函数的简单使用

    array filter函数 学习笔记 代码 function test odd var 先创建一个方法 方法是调动test odd函数 return var 1 返回条件 取奇数 a1 array a b c 2 3 4 11 23 ec
  • #vue# vue锚点定位,滚动到具体位置

    需求 点击导航栏的各个tab 跳转 滚动 到当前页面的具体位置 步骤 1 首先在导航栏的版块里面加入方法goToAnchor 以及 跳转的id类名 div class nav item center div About div div To
  • 查看.o, .obj文件符号列表,强大的nm命令

    nm命令可以查看 linux以及windows下的 o obj文件中的符号列表 其中 o文件可以由gcc g 编译得到 obj由vc编译得到 太爽了 以后遇到undefined reference错误的时候就可以这个命令搞定了 举一例子 在
  • 【java笔记】常用接口(2):Consumer接口

    Consumer接口是一个消费型接口 泛型指定什么类型 就可以使用accept消费什么类型数据 直接输出 public class Demo public static void main String args method asd na
  • 高德地图弹窗使用vue模板

  • android 遍历assets下的文件

    在AssetManager中有个list 方法 传入你的子文件名称即可 String flLists this getAssets list your subdir 如果是根目录 那么就是这么写 AssetManager assetMana
  • 集合框架的简要介绍

    目录 集合和数组的区别 Collection接口 ArrayList实现类 ArrayList的创建和使用 linkedList Set接口及其实现类 Set接口特点 HashSet实现类 HashSet特点 HashSet避免对象重复的规