数组和集合的区别
相同点:都是容器,可以储存多个数据
不同点:数组的长度是不可变的,集合的长度是可变的
数组可以存基础数据类型和引用数据类型,集合只能存引用数据类型
(如果存基础数据类型,需要存对应的包装类)
集合体系结构
Collection的常用方法
方法名 说明
boolean add(E e) 添加元素
boolean remove(Object o) 从集合中移除指定的元素
boolean removeif(Object o) 根据条件进行移除
void clear() 清空集合中的元素
boolean coontains(Object o) 判断集合中是否存在指定的元素
boolean isEmpty() 判断集合是否为空
int size() 集合的长度,集合中元素的个数
迭代器:集合专用的遍历方式
Iterator<E> iterator():返回此集合中元素的迭代器通过集合对象的 iterator()方法得到
iterator中常用的方法:
boolean hasNext():判断当前位置是否有元素可以被取出
E next():获取当前位置的元素,将迭代器对象移向下一个索引的位置
例:Collection<String> c = new ArrayList<>()
c.add("hello")
Iterator<String> it = c.iterator();
while(it.hasNext()){
String s = it.next();
System.out.println(s);
}
迭代器的删除方法:
void remove():删除迭代器对象当前指向的元素
增强for循环(foreach)
格式:for(集合/数组中的元素数据类型 变量名 :集合/数组名){}
List
特点:1、存取有序 2、可以重复 3、有索引
特有方法:
void add(int index,E element) 在此集合中的指定位置插入指定元素
E remove(int index) 删除指定索引处的元素,返回被删除的元素
E set(int index ,E element) 修改指定索引处的元素,返回被修改的元素
E get(int index) 返回指定索引处的元素
List集合的实现类
ArrayList:底层是数组结构实现,查询快、增删慢
LinkedList集合:底层是链表结构实现,查询慢、增删快
LinkedList特有的方法:
public void addFirst(E e) 在列表的开头插入指定的元素
Public void addLast(E e) 将指定的元素追加到此列表的末尾
public E getFirst() 返回此列表中的第一个元素
public E getLast() 返回此列表中的最后一个元素
public E removeFirst() 从此列表中删除并返回第一个元素
public E removeLast() 从此列表中删除并返回最后一个元素
Set集合
特点:1、不可以存储重复的元素 2、没有索引,不能使用普通for循环遍历
TreeSet:不可以存储重复的元素、没有索引、可以将元素按照规则进行排序
TreeSet():根据其元素的自然排序进行排序
TreeSet(Comparator comparator):根据指定的比较器进行排序
HashSet:
底层结构是哈希表
存取无序
不可以存储重复的元素
没有索引,不能使用普通for循环遍历
存储自定义类型元素,要想实现元素的唯一,必须重写hashCode方法和equal方法
Object 类中的public int hashCode():返回对象的哈希码值
哈希值的特点:
1、同一个对象多次调用 hashCode() 方法返回的哈希值是相同的
2、默认情况下,不同对象的哈希值是不同的。而重写 hashCode() 方法,
可以实现让不同对象的哈希值相同
哈希表结构:
节点个数少于等于8个:数组+链表
节点个数多于8个:数组+红黑树
Map:
interface Map<K,V> K:键的类型;V:值的类型
特点:双列集合,一个键对应一个值
键不可以重复,值可以重复
方法:
V put(K key,V value) 添加元素
V remove(Object key) 根据键删除键值对元素
void clear() 移除所有的键值对元素
boolean containsKey(Object key) 判断集合是否包含指定的键
boolean containsValue(Object value) 判断集合是否包含指定的值
boolean isEmpty() 判断集合是否为空
int size() 集合的长度,也就是集合中键值对的个数
获取方法:
V get(Object key) 根据键获取值
Set<K> keySet() 获取所有键的集合
Collection<V> values() 获取所有值的集合
Set<Map.Entry<K,V>> entrySet() 获取所有键值对对象的集合
HashMap:
底层是哈希表结构的
依赖hashCode方法和equals方法保证键的唯一
如果键要存储的是自定义对象,需要重写hashCode和equals方法
TreeMap:
底层是红黑树结构
依赖自然排序和比较器排序,对键进行排序
如果键存储的是自定义对象,需要实现Comparable接口
或者在创建TreeMap对象时候给出Comparator比较器排序规则
创建不可变集合
在List、Set、Map接口中,都存在of方法,可以创建一个不可变的集合
这个集合不能添加,不能删除,不能修改
但是可以结合集合的带参构造,实现集合的批量添加
在 Map 接口中,还有一个 ofEntries 方法可以提高代码的阅读性
首先会把键值对封装成一个Entry对象,再把这个Entry对象添加到集合当中
例:
List<String> list1 = List.of("a", "b", "c", "d");
ArrayList<String> list2 = new ArrayList<>(List.of("a", "b", "c", "d"));
Set<String> set = Set.of("a", "b", "c", "d", "a");
Map<String, String> map1 = Map.ofEntries(
Map.entry("小黄", "江苏"),
Map.entry("小蓝", "北京")
);
Map<String, String> map2 = Map.of("小黄", "江苏", "小蓝", "北京", "大黄", "上海");
并发集合类
ConcurrentHashMap:这是一个线程安全的哈希表,它提供了高效的并发读写操作。
ConcurrentHashMap 内部使用了分段锁技术,将哈希表划分为多个段,每个段独立加锁,
从而减少了锁的竞争,提高了并发性能,JDK 8之后,当链表长度大于等于8时,自动转换成红黑树结构。
CopyOnWriteArrayList:这是一个线程安全的ArrayList实现,它通过复制原始数据来实现对数据的修改。
当对列表进行修改操作时,它会创建一个新的列表副本,将修改后的数据写入新副本,
然后用新副本替换原始列表。这种方式适用于读操作远多于写操作的场景。
CopyOnWriteArraySet:这是一个线程安全的Set实现,它基于CopyOnWriteArrayList实现,
具有相同的特点和优缺点。
ConcurrentLinkedQueue:这是一个线程安全的队列,它提供了高效的并发入队和出队操作。
ConcurrentLinkedQueue内部使用了无锁数据结构,通过CAS操作实现对队列的并发访问。