16、集合

一、集合概述

1、为什么使用集合

(1)数组的不足

  • 长度开始时必须指定,而且一旦指定不能更改
  • 保存必须为同一类型的元素
  • 使用数组进行增加、删除元素较麻烦

(2)集合的优点

  • 可以动态保存任意多个对象,使用比较方便
  • 提供了一系列方便的操作对象的方法
  • 使用集合添加删除元素简洁

2、集合的框架

二、Collection接口

public interface Collection<E> extends Iterable<E> 

1、Collecting接口

(1)Collection实现子类可以存放多个元素,每个元素可以是Object

(2)有些Collection的实现类可以存放重复的元素,有些不可以

(3)有些Collection的实现类是有序的【List】,有些是无序的【Set】

(4)Collection接口没有直接的实现子类,是通过它的子接口Set和List来实现的

2、Collection接口遍历元素

(1)方式一:迭代器【Iterator】

【迭代器】

​ Iterator对象称为迭代器,主要用于遍历Collection集合中的元素

  • 所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象,即可以返回一个迭代器
  • Iterator仅用于遍历集合,Iterator本身不存放对象

【迭代器的执行原理】

  • 得到一个集合的迭代器:Iterator iterator = coll.iterator();
  • 判断是否还有下一个元素:iterator.hasNext()
  • 遍历:
while (iterator.hasNext()) {
    sout(iterator.next());
}

(2)方式二:增强for循环

【基本语法】

for (元素类型 元素名 : 集合名或数组名) {
    访问元素;
}

三、List接口

1、List接口

List接口时Collection接口的子接口

(1)List集合类中元素有序(即添加顺序和取出顺序一致)、且可重复

(2)List集合中每个元素都有其对应的顺序索引【支持索引】

(3)List容器中的每个元素都对应一个整数型的序号记载其在容器的位置,可以根据序号存取容器中的元素

2、List的三种遍历方式

(1)方式一:使用迭代器

Iterator iterator = list.iterator();
while (iterator.hasNext()) {
    Object obj = iterator.next();
    sout(obj);
}

(2)方式二:增强for

for (Object obj : list) {
    sout(obj);
}

(3)方式三:普通for

for (int i = 0; i < list.size(); i++) {
    sout(list.get(i));
}

四、ArrayList类

1、ArrayList概述

(1)ArrayList中维护了一个Object类型的数组elementData来实现数据的存储

(2)当创建ArrayList对象时,如果使用的是指定大小的有参构造器,则elementData容量为指定大小,扩容为原来1.5倍;如果使用的是无参构造器,则初始elementData容量为0,第一次添加,则扩容为10,若再次扩容,则扩容为1.5倍

2、源码分析

【见源码部分】

五、Vector类

1、Vector概述

(1)Vector底层也是一个对象数组

(2)Vector是线程同步的,即线程安全

2、Vector与ArrayList的比较

底层结构 效率 线程安全 扩容倍数
ArrayList 可变数组 效率高 不安全 【有参】
1.5倍
【无参】
(1)初始化容量为10
(2)再次扩容为1.5倍
Vector 可变数组 效率较低 安全 【有参】
2倍
【无参】
(1)初始化容量为10
(2)再次扩容为2倍

六、LinkedList类

1、LinkedList概述

(1)LinkedList底层维护了一个双向链表用来存储数据

(2)维护了firstlast两个属性分别指向首节点和尾节点,实现了双向链表和双端队列的特点

(3)每个节点为【Node对象】,里面维护了prev【指向前节点】,next【指向后节点】,item三个属性实现了双向链表

(2)可以添加任意元素(元素可以重复),包括null

(3)线程不安全,没有实现线程同步

2、源码分析

【见源码部分】

3、ArrayList和LinkedList比较

底层结构 增删的效率 改查的效率
ArrayList 可变数组 【较低】
数组容量需要变动
【较高】
LinkedList 双向链表 【较高】
链表追加
【较低】
需要遍历

(1)如果改查操作较多,选择ArrayList

(2)如果增删较多,选择LinkedList

(3)一般来说,80-90%都是查询,大部分情况选择ArrayList

(4)具体项目中,需要根据业务灵活选择

七、Set接口

1、Set接口

Set接口时Collection的子接口

(1)无序(添加和取出的顺序不一致),无索引

(2)不允许重复元素,最多包含一个null

2、Set接口的遍历方式

因为无索引,则无法用平台for循环

(1)迭代器

(2)增强for

八、HashSet类

(1)HashSet实现Set接口,底层基于HashMap实现,但与HashMap不同在于HashMap存储键值对,HashSet仅存储对象——key

(2)HashSet使用成员对象来计算hashcode值

(3)HashSet的特点

  • 无序性
  • 唯一性(允许使用null)
  • 本质上讲就是HashMap
  • HashSet没有提供get方法,和HashMap一样,因为Set内部是无序的,只能通过迭代的方式获得

九、Map接口

1、Map概述

(1)Map与Collection并列存在,用于保存具有映射关系的数据:Key-Value

(2)Map中的key和value可以是任何引用类型的数据,会封装到HashMap$Node对象中

(3)Map中的key不允许重复,重复会替换

(4)value可以重复

(5)key和value之间存在单向一对一的关系,即通过指定key总能找到对应的value

2、Map六大遍历方式

(1)containsKey:查找键是否存在

(2)keySet:获取所有的键

(3)entrySet:获取所有的键值对

(4)values:获取所有的值

package com.zyhstu.map_.sort_;

import java.util.*;

public class Test {

    public static void main(String[] args) {

        Map map = new HashMap();
        map.put("邓超", "孙俪");
        map.put("王宝强", "马蓉");
        map.put("宋喆", "马蓉");
        map.put("六零波", null);
        map.put( null, "刘亦菲");
        map.put("鹿晗", "关晓彤");

        //1、取出所有key,通过key取出对应的value
        Set keyset = map.keySet();
        /**Set接口两种遍历方法
         * (1)增强for
         * (2)迭代器
         */
        //(1)增强for
        for (Object key : keyset) {
            System.out.println(key + "-" + map.get(key));
        }
        //(2)迭代器
        Iterator iterator = keyset.iterator();
        while (iterator.hasNext()) {
            Object key =  iterator.next();
            System.out.println(key + "-" + map.get(key));
        }

        /**2、values:获取所有的值
         * (1)for循环
         * (2)增强for循环
         * (3)迭代器
         */
        Collection values = map.values();

        for (Object value : values) {
            System.out.println(value);
        }

        Iterator iterator = values.iterator();
        while (iterator.hasNext()) {
            Object value =  iterator.next();
            System.out.println(value);
        }

        //3、通过entrySet:获取所有键值对
        Set entrySet = map.entrySet();

        Iterator iterator = entrySet.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println(next);
        }

        for (Object o : entrySet) {

            Map.Entry m = (Map.Entry) o;
            System.out.println(m.getKey() + "-" + m.getValue());

            System.out.println(o);
        }
    }

}

十、HashMap类

(1)key不能重复,但是value可以重复,运行使用null键和null值

(2)如果添加相同的key会覆盖原来的键值对,等同于修改

(3)底层以hash表的方式存储数据,则不保证映射顺序

(4)线程不安全

十一、如何选择集合实现类

十二、Collections工具类

1、Collections工具类概述

(1)Collections是一个操作Set、List和Map等集合的工具类

(2)Collections中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作

2、排序操作(静态方法)

(1)reverse(List)`:反转list中元素的顺序

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

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

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

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

3、查找、替换

(1)Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素

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

(3)Object min(Collection)

(4)Object min(Collection, Object)

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

(6)void copy(List dest, List src):将sec的内容复制到dest中

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

posted @ 2022-03-08 23:47  DarkSki  阅读(35)  评论(0编辑  收藏  举报