首页 > 其他分享 >集合的学习

集合的学习

时间:2024-08-08 18:55:30浏览次数:7  
标签:元素 List 接口 学习 add 集合 c1

集合Collection,也是一个数据容器,类似于数组,但是和数组是不一样的。集合是一个可变的容器,可以随时向集合中添加元素,也可以随时从集合中删除元素。另外,集合还提供了若干个用来操作集合中数据的方法。

集合里的数据,我们称之为元素(elements);集合只能用来存储引用类型的数据不能存储八大基本数据类型的数据

泛型的引入

Java SE 5.0以前,集合的元素只要是Object类型就行,那个时候任何对象都可以存放在集合内,但是从集合中获取对象后,需要进行正确的强制类型转换。但是,Java SE 5.0 以后,可以使用新特性”泛型”,用来指定要存放在集合中的对象类型。避免了强制转换的麻烦。

集合与数组

  1. 数组是定长的容器,一旦实例化完成,长度不能改变。集合是变长的,可以随时的进行增删操作。

  2. 数组中可以存储基本数据类型和引用数据类型的元素,集合中只能存储引用数据类型的元素。

  3. 数组的操作比较单一,只能通过下标进行访问。集合中提供了若干个方便对元素进行操作的方法。

小贴士: 在存储引用类型时,集合与数组,存储的其实都是==对象的地址==。

Collection接口

Collection 接口是 List、Set 和 Queue 接口的父接口,该接口里定义了他们三个子接口的共同方法。既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合。作为父接口,其子类集合的对象,存储元素的特点,可能是无序的,也可能是有序的,因此在父接口中并没有定义通过下标获取元素的方法功能。

在进行集合的遍历的时候,方式其实很多。但是,基本上所有的遍历,都与 Iterable 接口有关。这个接 口提供了对集合集合进行迭代的方法。只有实现了这个接口,才可以使用增强for循环进行遍历。

public class CollectionDemo {
    public static void main(String[] args) {
        //使用多态的向上造型创建一个子类型对象
        Collection<String> c1 = new ArrayList<>();
        //1. E add(E e)  向集合中添加元素
        c1.add("A");
        c1.add("B");
        c1.add("C");
        //2. boolean isEmpty()
        boolean empty = c1.isEmpty();
        System.out.println("empty: " + empty);
        //3. int  size(): 返回的是集合元素的个数
        System.out.println(c1.size());
        //4. String toString()
        System.out.println(c1);
        Collection<String> c2 = new ArrayList<>();
        c2.add("B");
        c2.add("C");
        c2.add("D");
        //5. addAll(Collection c)
        c1.addAll(c2);
        System.out.println(c1);
        /*
         * 6. boolean contains(Object o):
         *    查看是否包含字符串 "B"
         */
        boolean b = c1.contains("B");
        System.out.println("是否包含字符串B :"+b);
        /*
         * 7. boolean containsAll(Collection c)
         *   查看c1是否包含c2
         */
        boolean b1 = c1.containsAll(c2);
        System.out.println("c1集合是否包含c2集合:"+b1);
        /*
         * 8. boolean  equals(Object o)
         *    测试: 创建一个新的集合c3  添加元素 "A" "B" "C" "B","D","D"
         *    判断两个集合是否相同
         */
        Collection<String> c3 = new ArrayList<>();
        c3.add("A");
        c3.add("B");
        c3.add("C");
        c3.add("B");
        c3.add("C");
        c3.add("D");
        System.out.println("c1和c3相同吗?  :" + c1.equals(c3));

        /** 9.  boolean  remove(Object o)
         *     移除c1集合里的元素B,并查看剩下的元素       */
        boolean d = c1.remove("B");
        System.out.println(" 移除元素B :" + d);
        System.out.println(c1);

        /**  10.  boolean  removeAll(Collection<?> c)
         *       解析: 从集合中删除另一个集合c中所具有的元素。
         *
         *      新建一个集合c4,  添加元素"B","C"
         *      测试c1移除子集c4                        */
        Collection<String> c4 = new ArrayList<>();
        c4.add("B");
        c4.add("C");
        c1.removeAll(c4);
        System.out.println(c1);

        /**   11.  boolean retainAll(Collection c)
         *      测试:向c1里添加"E","F","G",  然后保留子集c5,  c5里的元素有"A","E"   */
        c1.add("E");
        c1.add("F");
        c1.add("G");
        Collection<String> c5 = new ArrayList<>();
        c5.add("A");
        c5.add("E");
        c5.add("H");
        c1.retainAll(c5);
        System.out.println(c1);

        /** 12.  void clear():
         *      测试:清空c1                   */
        c1.clear();
        System.out.println(c1);
        System.out.println(c1.size());
    }
}
  • 增强for循环中不允许对集合中的元素进行修改,修改是无效的

  • 增强for循环中不允许对集合的长度进行修改,否则会出现 ConcurrentModificationException

for (String ele : collection) {
   System.out.println(ele);
}

迭代器Iterator,是一个接口, Collection集合中有一个方法 iterator() 可以获取这个接口的实现类 对象。在这个迭代器中,维护了一个引用,指向集合中的某一个元素。默认指向一个集合前不存在的元 素,可以认为是下标为-1的元素。

迭代器的工作原理:循环调用 next() 方法进行向后的元素指向,并返回新的指向的元素。同时,在向 后进行遍历的过程中,使用 hasNext() 判断是否还有下一个元素可以迭代。

在迭代器使用的过程中,需要注意:

  • 不允许对集合中的元素进行修改

  • 不允许对集合的长度进行修改

List子接口

  1. List 是一个元素有序、且可重复的集合,集合中的每个元素都有其对应的顺序索引,从0开始

  2. List 允许使用重复元素,可以通过索引来访问指定位置的集合元素。

  3. List 默认按元素的添加顺序设置元素的索引。

  4. List 集合里添加了一些根据索引来操作集合元素的方法

ArrayList和LinkedList

这两个类都是List接口的实现类(子类)。两者在实现上的底层原理对比

  • ArrayList是实现了基于动态数组的数据结构,对象存储在连续的位置上

  • LinkedList基于双链表的数据结构,链表中的每个节点都包含了前一个和后一个元素的引用。

  • 对于随机访问get和set,ArrayList绝对优于LinkedList,因为LinkedList要移动指针。

  • 对于插入和删除操作add和remove,LinkedList比较占优势,因为ArrayList要移动数据。

PS:当然,这些对比都是指数据量很大或者操作很频繁的情况下的对比,如果数据和运算量很小,那么对比将失去意义

Queue子接口

  • 队列Queue也是Collection的一个子接口,它也是常用的数据结构,可以将队列看成特殊的线性表,队列限制对线性表的访问方式:只能从一端添加(offer)元素,从另一端取出(poll)元素。

  • 队列遵循先进先出(FIFO first Input First Output)的原则

  • 实现类LinkedList也实现了该接口,选择此类实现Queue的原因在于Queue经常要进行添加和删除操作,而LinkedList在这方面效率比较高。

  • 其主要方法如下:

方法解析
boolean offer(E e)作用:将一个对象添加到队尾,如果添加成功返回true
E poll()作用:从队首删除并返回这个元素
E peek()作用:查看队首的元素

Deque

Deque是Queue的子接口,定义了所谓的”双端队列”,即从队列的两端分别可以入队(offer)和出队(poll)。同样,LinkedList实现了该接口

Set子接口

  1. Set集合中的元素是无序的(取出的顺序与存入的顺序无关)

  2. Set集合中的元素不能重复

    即不能把同一个东西或者相似的东西两次添加到同一个Set容器中,每次放入时都会进行判断是否存在,如果存在,就不添加。
    ​
    如果能放入,与我们的设计初衷相违背了。
     实现类
1)HashSet

HashSet 是 Set 接口的典型实现,大多数时候使用 Set 集合时都使用这个实现类。

HashSet 按 Hash 算法来存储集合中的元素,因此具有很好的存取和查找性能。

HashSet 具有以下特点:

  • 1) 不能保证元素的排列顺序

  • 2) HashSet 不是线程安全的

  • 3) 集合元素可以是 null

当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,然后根据 hashCode 值决定该对象在 HashSet 中的存储位置。

如果两个元素的 equals() 方法返回 true,但它们的 hashCode() 返回值不相等,hashSet 将会把它们存储在不同的位置,但依然可以添加成功。

2)LinkedHashSet
  • LinkedHashSet 是 HashSet 的子类

  • LinkedHashSet 集合根据元素的 hashCode 值来决定元素的存储位置,但它同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的。

  • LinkedHashSet 性能插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能。

  • LinkedHashSet 不允许集合元素重复。

3)TreeSet

TreeSet 是 SortedSet 接口的实现类, TreeSet集合是用来对元素进行排序的,同样他也可以保证元素的唯一。TreeSet 可以确保集合元素处于排序状态。

TreeSet 支持两种排序方法:自然排序和定制排序。默认情况下,TreeSet 采用自然排序

List排序

Comparable接口

如果集合里的元素想要排序,那么元素对象之间一定要有大小之分。这个大小之分是如何界定的呢??

此时,元素类型必须是Comparable接口的实现类,该接口提供了方法

  • int compareTo(T t) 。规范了其子类是可以比较的,因此子类必须重写此抽象方法。

比较规则:(默认升序)

  • 如当前对象大于给定对象,那么返回值应为>0的整数

  • 若小于给定对象,那么返回值应为<0的整数

  • 若两个对象相等,则应返回0

工具类提供的排序方法

Collections是集合的工具类,提供了很多便于我们操作集合的方法,其中就有用于集合排序的sort方法。

  • static void sort(List<T> list)

作用是对指定的集合元素进行自然排序。前提元素类型必须实现Comparable接口

 Comparator比较器接口

java类一旦定义好,就不要轻易再去修改它。因此当java类实现了Comparable接口,也就代表比较规则已经确定.

但是,有的时候我们想临时改变一下比较规则,怎么办呢?

此时我们可以采用Comparator接口回调的方式。它提供了一个抽象方法:

  • int compare(T o1 , T o2)

比较规则如下

  • 若o1>02, 则返回值应该>0

  • 若o1<o2,则返回值应该<0

  • 若o1==o2, 则返回值应该为0

工具类中提供了sort方法的重载方法

  • static void sort(List<T> list , Comparator c)

作用:使用比较器c,指定临时排序规则

Collections

Collections 是一个操作 Set、List 和 Map 等集合的工具类,提供了大量方法对集合元素进行排序、查询和修改等操作,还提供了对集合对象设置不可变、对集合对象实现同步控制等方法

排序操作
  • reverse(List):反转 List 中元素的顺序

  • shuffle(List):对 List 集合元素进行随机排序

  • sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序

  • sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序

  • swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换

2)查找、替换
  • Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素

  • Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素

  • Object min(Collection)

  • Object min(Collection,Comparator)

  • int frequency(Collection,Object):返回指定集合中指定元素的出现次数

  • boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值

Map接口

Map是集合框架中的另一个父接口,它用来保存具有映射(一对一)关系的数据,这样的数据称之为键值对(Key-Value-Pair)。key可以看成是value的索引。特点如下:

  • key和value必须是引用类型的数据

  • 作为key,在Map集合中不允许重复

  • key可以为null

  • key和value之间存在单向一对一关系,通过指定的key总能找到唯一,确定的value

根据内部数据结构的不同,Map接口有多种实现类,其中常用的有内部为hash表实现的

HashMap和内部为排序二叉树实现的TreeMap

HashMap的实现原理

HashMap的底层主要是基于数组和链表来实现的,它之所以有相当快的查询速度主要是因为它是通过计算散列码来决定存储的位置。HashMap中主要是通过key的hashCode来计算hash值的,只要hashCode相同,计算出来的hash值就一样。如果存储的对象对多了,就有可能不同的对象所算出来的hash值是相同的,这就出现了所谓的hash冲突

图中,紫色部分即代表哈希表,也称为哈希数组,数组的每个元素都是一个单链表的头节点,链表是用来解决冲突的,如果不同的key映射到了数组的同一位置处,就将其放入单链表中

装载因子及其HashMap优化

capacity:容量,hash表里bucket(桶)的数量,也就是散列数组大小

initial capacity:初始容量,创建hash表时,初始bucket的数量,默认构建容量为16,也可以使用特定容量。

size:大小,当前散列表中存储数据的数量

load factor:加载银子,默认值0.75也就是75%,当向散列表增加数据时,如果size/capacity的值大于loadfactor,则发生扩容并且重新散列(rebash)

性能优化:加载因子较小时,散列查找性能会提高,但是也浪费了散列桶空间容量。0.75是性能和空间相对平衡结果。在创建散列表时指定合理容量,减少rehash能提供性能

TreeMap

TreeMap 存储 Key-Value对时,需要根据 Key 对 key-value 对进行排序。TreeMap 可以保证所有的 Key-Value 对处于有序状态。

TreeMap 的 Key 的排序:

  • 自然排序:TreeMap 的所有的 Key 必须实现 Comparable 接口,而且所有的 Key 应该是同一个类的对象,否则将会抛出 ClasssCastException

  • 定制排序:创建 TreeMap 时,传入一个 Comparator 对象,该对象负责对 TreeMap 中的所有 key 进行排序。此时不需要 Map 的 Key 实现 Comparable 接口

Properties

Properties 类是 Hashtable 的子类,该对象用于处理属性文件

由于属性文件里的 key、value 都是字符串类型,所以 properties 里的 Key 和 Value 都是字符串类型的

标签:元素,List,接口,学习,add,集合,c1
From: https://blog.csdn.net/st03zy/article/details/141034154

相关文章

  • Springboot整合Flowable入门-学习笔记
    目录1、定义流程(画图)2、Springboot部署流程3、Springboot删除所有流程4、Springboot根据流程部署ID查询流程定义ID5、Springboot启动(发起)流程6、Springboot查询任务6.1全部任务6.2我的任务(代办任务)7、springboot审批任务1、审批通过2、驳回8、Springboot流程......
  • 【人工智能】【机器学习】-好书推荐之《Python神经网络编程》
    目录内容概览编程环境面向对象学习目标如果你是想要自学机器学习相关知识的读者,我相信看完这篇文章的介绍后,你会对机器学习有更清晰的认识。帮助你走进机器学习的殿堂。《Python神经网络编程》(原书名:MakeYourOwnNeuralNetwork)是一本深度学习领域的入门级书籍,由Tar......
  • 2024-8-7 算法学习
    P6136【模板】普通平衡树(数据加强版)题意:1,插入一个数;2,删除一个数3,查询一个数的排名4,查询第x个数5,查询x的前驱和后继重点在于分裂split和合并merge操作:1:分裂为X[0,x],Y[x+1,n],后rt=merge(X,x,Y)2:分裂为X[0,x-1],Y[x,x],Z[x+1,n]后Y=merge(Y.l,Y.r),后rt=merge(X,Y,Z);3......
  • Task2 - IDA学习【进度 - 第二课】
    学习目标:-无名侠的课,看二进制培训(第二集和第三集)(https://space.bilibili.com/7761039/video)-会反汇编-会字符串搜索(f12)-会简单异或解密了解一下操作系统linux系统的可执行文件的后缀windows系统的可执行文件的后缀了解安装die(DetectItEasy)......
  • 卷积神经网络--卷积层(斯坦福李飞飞学习笔记)
    卷积核对于图像分类任务,常见的卷积核(kernel)大小可以是3x3、5x5个像素点注意一下词汇的辨析:kernel是二维的,也就是每一层的卷积核大小;filter表示的是三维的,所以可以看到ppt里面的filter展示的是5*5*3,因为kernel的大小是5*5,同时放入的图像是RGB类型,总共3个像素层,所以三维的filt......
  • Java学习进程6
    大家好!这是我学习Java的第六周,今天我想和大家分享一下这一周我所做的事情、下周的计划、遇到的问题以及如何解决这些问题。本周学习内容在这一周,我继续深入学习Java语言的核心概念,特别是对面向对象编程(OOP)的理解。我复习了类和对象的定义,同时也对封装、继承和多态这三个重要概念......
  • 【Python机器学习】利用AdaBoost元算法提高分类性能——基于单层决策树构建弱分类器
    单层决策树(也称决策树桩)是一种简单的决策树。它基于单个特征来做决策,由于这棵树只有一次分裂过程,因此它实际上就是一个树桩。在构造AdaBoost代码时,首先通过一个简单数据集来确保在算法上一切就绪:fromnumpyimport*defloadSimpData():datMat=matrix([[1.0,2.1],......
  • 机器学习算法之一 线性回归
    1.线性预测函数定义左侧为真实值,右侧为预测值与误差的和,其中为权重矩阵。2.目标函数的推导2.1高斯分布函数误差符合独立同分布假设,服从均值为0的高斯分布:将线性函数带入,得:......
  • 机器学习的数学基础--向量,矩阵
    机器学习与传统编程的一个重要区别在于机器学习比传统编程涉及了更多的数学知识。不过,随着机器学习的飞速发展,各种框架应运而生,在数据分析等应用中使用机器学习时,使用现成的库和框架成为常态,似乎越来越不需要数学知识了。其实,现成的库和框架只是帮助我们简化机器学习的开发任务,如......
  • 大数据框架之一——Hadoop学习第三天
    1、MapReduce概述及原理MapReduce是一种分布式计算模型,由Google提出,主要用于搜索领域,解决海量数据的计算问题.MapReduce是分布式运行的,由两个阶段组成:Map和Reduce,Map阶段是一个独立的程序,有很多个节点同时运行,每个节点处理一部分数据。Reduce阶段是一个独立的程序,有很多个节......