【JavaSE】十一、集合

本文详细介绍了Java集合框架,包括Collection和Map接口及其子接口如List、Set、HashMap等。重点讲解了Iterator迭代器和foreach循环的使用,以及ArrayList、LinkedList、HashSet、TreeSet等常见集合类的特点和操作方法。此外,还阐述了Map接口的常用方法,如HashMap、TreeMap和Properties,并提到了Collections工具类提供的排序、查找、替换和同步控制功能。

集合框架概述

集合可分为Collection和Map两种体系

  • Collection接口:单列数据,定义了存取一组对象的方法的集合
    • List接口:元素有序、可重复的集合
      • ArrayList、LinkedList、Vector
    • Set接口:元素无需、不可重复的集合
      • HashSet、LinkedHashSet、TreeSet
  • Map接口:双列数据,存储(key-value)对的数据
    • HashMap、LinkedHashMap、TreeMap、Hashtable、Properties

在这里插入图片描述在这里插入图片描述

Iterator迭代器接口

Iterator对象成为迭代器【设计模式的一种】,用于遍历集合元素

提供一种方法访问一个容器(container)对象中各个元素,而又不暴露该对象的内部细节。

Collection接口继承了java.lang.Iterable接口,有一个iterator()方法,用以返回一个实现了Iterator接口的对象

Iterator仅用于遍历集合,本身不提供承装对象的能力,若要创建Iterator对象,必须有一个被迭代的集合

集合对象每次调用Iterator()都得到一个全新的迭代器对象,默认游标在集合的第一个元素之前。

方法:

while (iterator.hasNext()){
            //next():1,指针下移  2.将下移后集合位置上的元素返回
            Object o=iterator.next();
            System.out.println(o);
        }

remove():在遍历期间删除集合中的元素,不同于集合直接调用remove()

foreach

Java5.0提供,不需获取Collection或数组的长度,无需索引访问元素

遍历集合的底层使用Iterator完成操作

for(要遍历的元素类型 遍历后自定义名称【局部变量】 : 要遍历的结构名称){

}

Person[] persons=new Person[5];
        persons[0]=new Person("1号",1);
        persons[1]=new Person("2号",2);
        persons[2]=new Person("3号",3);
        persons[3]=new Person("4号",4);
        persons[4]=new Person("5号",5);
        for (Person person:persons){
            System.out.println(person.getName());
        }

Collection接口方法

contains(Object o):判断当前集合是否包含obj

判断时调用的是obj所在类的equals方法,将集合内每个元素作为参数填入该对象的equals方法进行比较。

containsAll(Collection coll1):判断coll1中的所有元素是否都存在于当前集合中

remove(Object obj):调用obj所在类的equals方法,找到第一个相同的对象删除。删除成功则返回true

removeAll(Collection coll1):从当前集合中移除coll1中所有的元素

retainAll(Collection coll1):获取当前集合与coll1的交集,返回给当前集合

hashCode():返回当前对象的哈希值

toArray():集合→数组

Array.asList():数组→集合【List】

Collection子接口一:List

ArrayList、LinkedList、Vector是常见的实现类

同:三个类都实现了List接口,存储数据特点相同【有序、可重复】

  • ArrayList:主要实现类,线程不安全,效率高,底层用Object[]存储
    • 为防止多次扩容,建议使用带参构造器初始化大概容量
  • LinkedList:线程不安全,对于频繁插入、删除操作效率比ArrayList高,底层使用双向链表存储
  • Vector:古老实现类,线程安全,效率低,底层用Object[]存储

常用方法:

增:add(Object obj)

删:remove(int index)并返回该元素,remove(Object obj)

改:set(int index,Object obj)

查:get(int index)

插:add(int index,Object obj)

遍历:Iterator迭代器,增强for,普通循环

Collection子接口二:Set

无序性:不等于随机性,存储的数据并非按照数组索引顺序添加,而是根据数据哈希值决定的

不可重复性:保证添加的元素按照equals()判断时,不能返回true【相同的元素不能添加进来】

HashSet

  • 主要实现类,线程不安全,可以存null

  • Set的典型实现,按照Hash算法存储集合中的元素,因此有很好的存储、查找、删除的功能

  • 添加元素的过程

    1.向HashSet添加元素a时,先调用a所在类的hashCode()计算其哈希值。此哈希值通过某种算法计算出在HashSet底层数组中存放的位置【索引位置】

    2.判断底层数组此位置是否已有元素

    若无其他元素,则元素a添加成功【情况1】

    若有其他元素b(或已存在以链表形式存在的多个元素),则比较元素a与元素b的哈希值:

    若哈希值不相同,则元素a添加成功【情况2】

    若哈希值相同,则调用元素a所在类的equals()方法,将哈希值相同的对象与a比较:

    若equals()返回false,则元素a添加成功【情况3】

    若equals()返回true,则元素a添加失败

    对于情况2和情况3而言,元素a与已存在与索引位置上的数据以链表方式存储【七上八下】

    jdk7:元素a放到数组中,指向原来的元素

    jdk8:原来的元素在数组中,指向元素a

    要求:

    向Set中添加的数据,所在的类一定要重写hashCode()和equals()

    重写的hashCode()和equals()尽可能保证一致性【相等的对象一定要有相等的散列码】

  • LinkedHashSet

    HashSet的子类,遍历其内部顺序可根据添加顺序遍历

    • 根据元素的hashCode决定元素的存储位置
    • 用双向链表维护元素次序,使得元素看上去像是以插入顺序保存的
    • 性能略低于HashSet,但是迭代访问Set里的全部元素性能更佳

TreeSet

  • SortedSet接口实现类,确保集合元素处于排序状态,有序、查询速度快
  • 添加的数据要求是相同类的对象
  • 可按照添加对象的指定属性进行排序
  • 底层使用红黑树结构存储数据
  • 两种排序方法:自然排序(实现Comparable接口)【默认】和定制排序(Comparator)
    • 自然排序中,比较两个对象相同的标准是:compareTo()返回0,不再是euqals()
    • 定制排序中,比较两个对象相同的标准是:compare()返回0,不再是equals()

Map接口

结构

key:无序、不可重复,使用Set存储所有的key【以hashMap为例:key所在类要重写equals()和hashCode()】

value:无序、可重复,使用Collection存储所有的value【value所在的类要重写equals()】

一对key-value构成了一个Entry对象

entry:无序的、不可重复的,使用Set存储所有的Entry

常用方法

  • 添加、删除、修改
    • Object put(Object key,Object value):将指定键值对添加/修改到当前map对象中
    • void putAll(Map m):将m中所有键值对存放到当前map
    • Object remove(Object key):移除指定key的键值对并返回value
    • void clear():清空map
  • 查询
    • Object get(Object key):获取指定key对应的value
    • boolean containsKey(Object key):是否包含指定key
    • boolean containsValue(Object value):是否包含指定value
    • int size():返回map中key-value对的个数
    • boolean isEmpty():判断当前map是否为空
    • boolean equals(Object obj):判断当前map和参数对象obj是否相等
  • 元视图操作
    • Set keySet():返回所有key构成的Set集合
    • Collection values():返回所有value构成的Collection集合
    • Set entrySet():返回所有key-value对构成的Set集合

HashMap

Map主要实现类,线程不安全,效率高,可以存储null的键值

底层:数组+链表(jdk7及之前),数组+链表+红黑树(jdk8)

LinkedHashMap

  • 保证遍历map元素时,可以按照添加顺序实现遍历(在原有hash底层基础上添加了一对指针,指向先后元素)
  • 对于频繁遍历操作,效率高于HashMap

TreeMap

  • 要求key必须是同一个类创建的对象
  • 保证按照添加的key-value进行排序,实现排序遍历【按照key自然排序/定制排序】
  • 底层使用红黑树

Hashtable

Map的古老实现类,线程安全,效率低,不能存储null的键值

Properties

常用来处理配置文件,key和value都是String类型

				Properties pros=new Properties();
        FileInputStream fis=new FileInputStream(new File("jdbc.properties"));
        pros.load(fis);
        String user = pros.getProperty("user");
        String password = pros.getProperty("password");
        System.out.println(user);
        System.out.println(password);
        fis.close();

Collections工具类

Collections是一个提供操作Set、List、Map的工具类

排序

reverse(List):反转列表

shuffle(List):对列表进行随机排序

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

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

swap(List,int,int):将列表中两个索引处元素呼唤

查找、替换

Object max/min(Collection):根据元素自然排序返回最大/小元素

Object max/min(Collection,Comparator):根据Comparator指定顺序,返回最大/小元素

int frequency(Collection,Object):返回元素出现次数

void copy(List dest,List src):将src复制到dest

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

同步控制

将指定集合包装成线程同步的集合,解决线程安全问题

sychronizedCollection(Collection)

sychronizedList(List)

sychronizedMap(Map)

sychronizedSet(Set)

sychronizedSortedMap(SortedMap)

sychronizedSortedSet(SortedSet)

<think>好的,我现在需要处理用户的问题,他想了解Java SE中的集合框架使用指南。首先,我得回忆一下用户之前提供的引用内容,引用[1]里提到了HashSet、LinkedHashSet和TreeSet的区别,以及它们的存储顺序。引用[2]则涉及Iterator接口和Map的部分信息。用户现在需要的是一个使用指南,所以应该涵盖集合框架的主要接口和实现类,以及如何选择和使用它们。 首先,我应该从集合框架的整体结构入手,分清楚层次结构。Java集合框架主要分为Collection和Map两个根接口,Collection下又有List、Set、Queue等子接口,而Map是独立的。需要详细说明每个接口的特点和常用实现类。 接下来,对于每个接口,比如List,要比较ArrayList、LinkedList和Vector的区别,包括它们的线程安全、性能特点。Set部分已经引用了HashSet、LinkedHashSet和TreeSet,可能需要再补充它们的应用场景和使用注意事项。Map接口的话,HashMap、LinkedHashMap、TreeMap以及HashTable和ConcurrentHashMap的区别也很重要,特别是线程安全和排序特性。 然后,需要提到工具类Collections和Arrays,它们提供的排序、查找等方法,以及如何通过它们来操作集合。此外,迭代器Iterator和ListIterator的使用也是关键点,用户可能关心如何遍历集合以及并发修改异常的问题。 性能分析方面,要根据不同数据结构的底层实现,比如数组、链表、红黑树等,说明它们的增删改查时间复杂度,帮助用户选择合适的集合类。例如,ArrayList的随机访问快,但插入删除慢;LinkedList相反。 线程安全部分,需要明确哪些集合是线程安全的,比如Vector、HashTable,以及如何通过Collections工具类将非线程安全的集合转换为线程安全的。另外,Java 5之后引入的并发包中的类如ConcurrentHashMap也是重点。 最后,要给出选择集合的指南,根据是否需要有序、唯一性、线程安全等因素来推荐合适的实现类。可能还需要提醒使用泛型来保证类型安全,避免运行时错误。 现在需要检查是否有遗漏的部分,比如Queue接口,但用户提供的引用里没有提到,可能需要简要说明。另外,要确保回答结构清晰,分点列出,每个部分都有小标题,方便用户阅读。同时,按照用户的要求,行内公式用$...$,但可能数学公式不多,不过如果有排序算法之类的可以提及,比如快速排序的时间复杂度是$O(n \log n)$。 还要注意生成相关问题,根据用户之前的示例,可能的问题包括不同集合的选择、线程安全处理、性能比较、排序方法等。需要确保问题相关且有助于用户进一步学习。 现在开始组织内容,确保每个部分简明扼要,重点突出,避免过于冗长。同时引用用户提供的引用内容,比如在讲Set的时候引用[1],在讲Iterator的时候引用[2]。最后检查LaTeX格式是否正确,比如时间复杂度用$O(n)$这样的格式。</think>### Java SE 集合框架使用指南 Java集合框架是处理对象集合的核心工具库,包含接口、实现类及算法。以下是关键组成部分及使用建议: --- #### 一、核心接口与实现类 1. **Collection接口** - **List(有序可重复)** - `ArrayList`:基于动态数组,随机访问快($O(1)$),插入删除慢($O(n)$)[^1] - `LinkedList`:基于双向链表,插入删除快($O(1)$),随机访问慢($O(n)$) - `Vector`:线程安全的动态数组,性能较低(已逐渐被替代) - **Set(无序唯一)** - `HashSet`:基于哈希表,元素无序($O(1)$查询)[^1] - `LinkedHashSet`:维护插入顺序的哈希表(适合需要顺序的场景)[^1] - `TreeSet`:基于红黑树,元素按自然顺序或自定义顺序排列($O(\log n)$操作)[^1] - **Queue(队列)** - `LinkedList`:可作普通队列 - `PriorityQueue`:基于堆的优先级队列 2. **Map接口(键值对)** - `HashMap`:哈希表实现,键无序($O(1)$查询) - `LinkedHashMap`:维护插入顺序或访问顺序 - `TreeMap`:基于红黑树,按键排序 - `HashTable`:线程安全但性能低(建议用`ConcurrentHashMap`替代) --- #### 二、工具类与算法 - **`Collections`工具类** 提供排序、查找、同步化等方法: ```java List<Integer> list = new ArrayList<>(); Collections.sort(list); // 排序 Collections.synchronizedList(list); // 转换为线程安全集合 ``` - **`Arrays`工具类** 用于数组操作: ```java int[] arr = {3,1,4}; Arrays.sort(arr); // 数组排序 ``` - **迭代器`Iterator`** 遍历集合的标准方式,避免并发修改异常[^2]: ```java Iterator<String> it = list.iterator(); while(it.hasNext()) { System.out.println(it.next()); } ``` --- #### 三、性能与选择建议 1. **选择依据** - **是否需要唯一性** → 选择`Set`或`Map` - **是否需要顺序** → `List`或`LinkedHashSet`/`LinkedHashMap` - **是否需要排序** → `TreeSet`/`TreeMap` - **线程安全需求** → `ConcurrentHashMap`、`CopyOnWriteArrayList` 2. **时间复杂度对比** | 操作 | ArrayList | LinkedList | HashMap/TreeMap | |----------------|-----------|------------|-----------------| | 随机访问 | $O(1)$ | $O(n)$ | $O(1)$/$O(\log n)$ | | 插入/删除(中间)| $O(n)$ | $O(1)$ | - | --- #### 四、线程安全处理 - **同步包装器**:通过`Collections.synchronizedXXX()`转换非线程安全集合 - **并发集合**:优先使用`java.util.concurrent`包中的类(如`ConcurrentHashMap`) --- #### 五、最佳实践 1. 使用泛型明确集合类型:`List<String> list = new ArrayList<>();` 2. 避免在遍历时修改集合(除非使用迭代器的`remove()`方法)[^2] 3. 需要频繁增删时优先选`LinkedList`,需要快速查询时选`ArrayList` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值