Java-----集合
目录
集合概述
Collection接口
List 接口及实现类
Arraylist的常用方法
List 接口及实现类
List接口集合迭代
Set 接口
Set 接口集合迭代
Map 接口
Map接口概述
HashMap
编辑
TreeMap
Hashtable
Map集合遍历
Collections类
我们假定要存储一个班学员信息,我们就需要一个类似于数组的容器来存储学员信息

数组有什么缺点?
数组的长度一旦被定义就不能修改
然而我们在实际开发中需要存储的数据大部分情况下都是会增长的,于是我们就需要一些能动态变化长度的容器来存储数据
我们要存储数据的逻辑和类型可能各式各样,所以我们就需要不同的数据结构,java对这些数据结构的实现就是我们集合
集合概述
Java的集合框架是由很多接口、抽象类、具体类组成的,都位于java.util包中

Collection接口
Collection接口定义了存储一组数据的方法,其子接口List和Set分别定义了存储方式
1.List有存储顺序(添加顺序)能存储重复数据
2.Set不能存储重复数据
List 接口及实现类
1.ArrayList是长度可变的数组,在内存中分配连续的空间。 遍历元素和随机访问元素的效率比较高
2.LinkedList采用链表存储方式。插入、删除元素时效率比较高
Arraylist的常用方法
- add(E element) 向尾部添加元素
- add(int index, E element) 向指定位置添加元素,效率较慢,因为指定的位置后面的所有元素都需要后移一位。
- addAll(Collection<? extends E> c) 将一个指定集合的所有元素添加到当前集合中
- remove(int index) 将指定位置的元素移出集合,并返回
- remove(Object o) 将指定的元素移出结合,成功返回true,失败返回false
- clear() 清除集合内的所有元素
- set(int index, E element) 替换指定位置的元素
- indexOf(Object o) 寻找指定元素在集合中第一次出现的为主
- isEmpty() 判断结合是否为空 为空返回true,非空返回false
- contains(Object o) 判断集合中是否有指定与元素
- get(int index) 获取指定位置的元素,与remove不同的是get不会将位置的元素移出集合
- size() 获得集合的长度
- toArray(T[] a) 将集合转换成指定类型的数组
List 接口及实现类
- add(E e)
- add(int index,Eelement)
- set(int index, E element)
- get(int index)
- removeFirst()
- contains(Object o)
- isEmpty()
- getFirst() 拿到链表第一个数
- getLast() 拿到最后一个数
- addFirst(Eelement) 从链表第一个数添加
- addLast(Eelement) 从最后一个数添加
- removeLast()
- remove(int index)
List接口集合迭代
for循环
增强for循环
迭代器迭代
ArrayList<Integer> arrayList = new ArrayList<>();//将数据添加到集合中for (int i = 0; i < 10; i++) {arrayList.add(i);}//for循环遍历for (int i = 0; i < arrayList.size(); i++) {System.out.println(arrayList.get(i));}//增强for循环遍历for (Integer integer:arrayList){System.out.println(integer);}//遍历器遍历Iterator<Integer> iterator = arrayList.iterator();while (iterator.hasNext()){int i= iterator.next();System.out.println(i);} 那么对于三种遍历方式各有优缺点
对于for循环
优点:可直接访问索引,适合需要索引的场景
对支持随机访问的集合(如Arraylist),性能高效
缺点:
- 仅适用于支持索引的集合
- 对非随机访问集合低效:每次通过索引访问需从头部遍历
- 易出错:需手动维护索引,易导致索引越界
对于增强for循环:
优点:
- 代码简洁安全:无需手动维护索引或迭代器,减少出错概率。
- 对非随机访问集合优化:如
LinkedList,内部通过迭代器实现,避免索引遍历的低效问题。
缺点:
- 无法获取索引
- 遍历时禁止修改集合结构:在遍历过程中增删元素会抛出
ConcurrentModificationException - 性能略低于迭代器:对
ArrayList等随机访问集合,需通过get()方法获取元素,而迭代器可直接访问内部数据。
对于迭代器
优点:
- 安全修改集合:通过
iterator.remove()可在遍历中删除元素(需在next()后调用),避免ConcurrentModificationException。 - 精细控制:支持
hasNext()、next()、remove()等操作,可实现复杂遍历逻辑 - 性能优化:对非随机访问集合(如
LinkedList),迭代器通过内部指针直接定位节点,效率高于普通for循环。
缺点:
- 代码冗长:需显式创建迭代器并管理遍历逻辑,代码量较大。
Set 接口
Set接口继承了Collection接口。Set中所存储的元素是不重复的,Set中的元素是没有索引的、
1.HashSet
HashSet类底层基于哈希表实现,元素位置是散列无序的
哈希(散列)本质就是一个数组, 算出余数是多少就存在对应的位置,存储的原始无序。他们都会more对16取模
2.TreeSet
TreeSet底层基于树形结构实现,元素进行指定方式的排序。存储的类型必须实现Comparable接口。
在存储过程中会默认排序,以第一个存储的数为根,其他的数与他进行比较大小,比他大的在右边,比他小的在左边,因为每个即将要存储进的数据都要进行对比,所以他无法存储相同的元素。
Set 接口集合迭代
1.增强for循环
2.迭代器遍历
Map 接口
Map接口概述
实现了Map接口的集合类都是双列集合
是一组键值对映射的
键不能重复,每个键只能映射到一个值
值可以重复
有三个实现类
1.HashMap
2.TreeMap
3.Hashtable
- V put(K key,V value) 向指定位置添加KV键值对
- V remove(Object key) 在集合中移除指定的Key,并返回
- void clear() 清空集合
- boolean containsKey(Object key) 查看是否含有指定Key
- boolean containsValue(Object value) 查看是否含有指定Value
- boolean isEmpty() 查看集合是否为空
- int size() 返回集合的大小
- V get(Object key) 通过Key拿到Value的值
- Collection<V> values() 将Map中所有的Value转换成指定类型的单列模式
- Set<K> keySet() 将Key转换成指定的Set集合
HashMap
基于哈希表的实现类,不保证映射的顺序
并允许使用一个为null的键,值都可以为null
在创建HashMap的时候可以定义两个范式,我们建议key定义String类型HashMapd可以存储一个key是null的格子,key只能有一个是null values有几个都可以。
他底层用到的数据结构:哈希表(数组)链表,红黑树。
他底层用到的数据结构:哈希表(数组)链表,红黑树。
哈希表默认长度是16,用哈希表也就是数组可以提高查询效率,然后使用key计算,运算过程就是用他的哈希值与数组的长度进行取模运算一个哈希值找到位置了之后如果这个位置上没有元素,那就直接将元素储存在这个节点上,如果继续添加元素,出现相同位置,先比较两者是否相同,如果不同,把后一个元素挂在第一个元素的后面形成一个链表,当链表的长度到达一定长度之后回转为红黑树。既可以存储更多的元素还可以提高查询效率。
哈希表扩容会一次扩容两倍。链表转红黑树的条件是链表的长度等于八,而且哈希表的长度要大于64;如果哈希表的长度小于64,那么就会先把哈希表扩容乘二。也就是链表的长度第三次等于8,长度为八的链表才会转换成红黑树。
TreeMap
基于红黑树结构的实现类,可以通过key的自然排序。
但是如果想使用引用的数据类型来作为key排序时,引用类要对Comparable接口重写。
Hashtable
实现了同步和线程
也是哈希结构的,方法都加了锁,在多线程场景下使用是安全的,
不能存储为null的键和值。因为在源码中要调用key的hashCode(),而null是一个关键字,不是面向对象中的内容,所以无法调用,所以无法创建null的key。
Map集合遍历
方式1:根据键找值
获取所有键的集合
遍历键的集合,获取到每一个键
根据键找值
方式2:根据键值对对象获取键和值
获取所有键值对对象的集合
遍历键值对对象的集合,获取到每一个键值对对象
根据键值对对象找键和值
HashMap<String,String> map = new HashMap<>();map.put("x", "xx");map.put("a", "aa");map.put("u", "uu");map.put("k", "kk");/*方式1: 先拿到所有的key,循环key,每次拿到一个key,然后再上map中去找值 (不推荐)*/Set<String> keyset = map.keySet();for (String key:keyset){System.out.println(key+":"+map.get(key));}/*方式2: 为了遍历方便,把所有的键值对,重新进行提取,存储到一个entry类型集合中 (开发中推荐的 效率高)*/Set<Map.Entry<String, String>> entries = map.entrySet();for (Map.Entry<String,String> entry :entries){System.out.println(entry.getKey()+":"+entry.getValue());} Collections类
Collections是集合类的工具类,与数组的工具类Arrays类似.
- binar ySearch(List<? extends Comparable<? super T>> list, T key)
- sort(List<T> list)
- swap(List<?> list, int i, int j)
- copy(List<? super T> dest, List<? extends T> src) ; 注意 dest size需大于等于
- src.size
- fill(List<? super T> list, T obj)
- max(Collection<? extends T> coll)
- min(Collection<? extends T> coll)
- replaceAll(List<T> list, T oldVal, T newVal)
- reverse(List<?> list)
- shuffle(List<?> list) 随机排序
- copy(dest,src)集合复制

