有容乃大
——Java集合(List/Set/Map)
- 数据结构的概念
- 数据结构定义:
数据结构是计算机对数据存储的一种安排。
就是计算机组织、存储数据的方式。
数据结构有哪些?
堆、栈、数组、队列、链表、散列表(hash)、图、树
数组\链表
- 理解1:对数据安排是可以有多种,所以数据结构是多样的
- 理解2:特定数据结构组成的数据,它应该有一些规律。有不同的特点
精心选择的数据结构可以带来更高的运行或者存储效率
- List列表
- 集合框架的体系
- 使用环境
有序(添加顺序),不可重复。
- 继承体系
Collection(所有集合类接口的超级接口)
|--List:特点 有序(添加的顺序)可以重复的数据
|--ArrayList :查询和修改效率高,但是删除和插入效率低。(线程不安全)
|--LinkedList :插入和删除效率高 (线程不安全)
|--Vector :线程安全
- 如何选择
- 有序(添加的顺序)可以重复的数据
- 如果查询和修改的频率高-ArrayList
- 如果插入删除频率高-LinkedList
- 如果要求线程安全 Vector
- ArrayList
- 基本数据的维护 常用的CRUD 方法
ArrayList() 构造一个初始容量为 10 的空列表
ArrayList(Collection<? extends E> c) 构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。
ArrayList(int initialCapacity) 构造一个具有指定初始容量的空列表。
public void add(int index,E element) 将指定的元素插入此列表中的指定位置。向右移动当前位于该位置的元素(如果有)以及所有后续元素(将其索引加 1)。
boolean add(E e) 将指定的元素添加到此列表的尾部。
void clear() 移除此列表中的所有元素。
boolean contains(Object o) 如果此列表中包含指定的元素,则返回 true。
E get(int index) 返回此列表中指定位置上的元素。
E remove(int index) 移除此列表中指定位置上的元素。
boolean remove(Object o) 移除此列表中首次出现的指定元素(如果存在)。
boolean b = list.remove("A");//false 如果列表不包含此元素,则列表不做改动。
int size() 返回此列表中的元素数。
E set(int index, E element) 用指定的元素替代此列表中指定位置上的元素。
Object[] toArray() 按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组。
static <T> List<T> asList(T... a) 返回一个受指定数组支持的固定大小的列表。
- 集合的遍历
- for可以得到下标
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
- 增强for循环无法获取下标
for (Object object : list) {
System.out.println(object);
}
- 迭代器
- 单向迭代器
Iterable 接口 有接口方法 Iterator<T> iterator();
返回一个Iterator
boolean hasNext() 判断是否有下一个元素,如果返回true表示有下一个;
Object next() 返回下一个元素(要移动指针);
void remove() 删除下一个元素
注意:如果尚未调用 next 方法,或者在上一次调用 next 方法之后已经调用了 remove 方法
异常:ConcurrentModificationException:不能在迭代过程中对数据源进行改变
- 双向迭代器
listIterator是List下面的方法
Iterator 单向的迭代器接口,从左到右依次获得数据,判断是否有下一个;获得下一个
|-- ListIterator 双向的迭代器接口,它的主要方法如下:
Iterator中有的它也有;
boolean hasPrevious() 判断是否有上一个;
Object previous() 获得上一个元素;
迭代器
Iterable-->一个接口,方法 : Iterator<T> iterator()
Iterator<T> iterator() 返回一个在一组 T 类型的元素上进行迭代的迭代器。
|-- boolean hasNext(); 如果仍有元素可以迭代,则返回 true
|-- Object Next(); 返回迭代的下一个元素。
|-- void remove() 从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)
所有的list的实现类都可以获取 这个对象
- LinkedList
基于数据结构的不同,他提供了很多操作头 和尾的方法
特点:
- 内部是基于双向链表结构实现的。添加和删除比较快,查询相对ArrayList比较慢
- 内部相对于ArrayList而言多了一些操作头和尾的方法
- 可以充当队列,堆栈
- 不是线程安全的(同步的)
总结:LinkedList底层是基于双向链表容器类,添加和删除比较快。查找和修改较慢。
- Set集合
- 使用的大环境
无序(添加的顺序)、不重复
- HashSet
- 判断重复的标准
hashCode&&equals
hashCode:建议自动生成
equals:建议自己去写
- 根据自己的业务场景决定覆写方法的逻辑
例:
public boolean equals(Object obj) {
if (obj instanceof Cat) {//1.判断实际是否是同一类型
Cat c = (Cat)obj;//是则强转
if (c.getAge() == this.age) {//2.继续判断年龄是否相等
if (c.getName().equals(this.getName())) {//3.最后判断年龄是否相同
return true;
}
}
}
return false;
}
- TreeSet
- 有排序的功能
public interface Comparable<T> 此接口强行对实现它的每个类的对象进行整体排序。(自然排序)
|-- int compareTo(T o) 比较此对象与指定对象的顺序
- Comparator
用于自定义比较器:在创建TreeSet对象时给一个比较器给对象
- Comparable
自然排序:自定义类时实现的接口,覆写compareTo方法,自定义排序逻辑
- 集合的体系
- Map映射
- Map的概念
接口 Map :将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
实现的类:
- HashMap
- TreeSet
- 方法
put(K key, V value) 在此映射中关联指定值与指定键。 |
put方法特点:
- 如果key不存在,直接添加进去
- 如果key相同,value值使用最新的值替换key对应的老值(被覆盖的值)
put方法会返回 对应key对应的老值
boolean containsKey(Object key) 如果此映射包含对于指定键的映射关系,则返回 true。
boolean containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回 true。
get(Object key) 返回指定键所映射的值。(通过键得到值)
putAll(Map<? extends K,? extends V> m) 将指定映射的所有映射关系复制到此映射中,这些映射关系将替换此映射目前针对指定映射中所有键的所有映射关系。(相当于Collection下面的addAll,把另外一个Map放到当前Map的容器里面)
remove(Object key)从此映射中移除指定键的映射关系(通过key ,找到value,然后把一对键和值都删掉)。
- 特点
HashMap 判断重复的标准和HashSet一致,通过键的hashcode和equals;
TreeMap 判断重复的标准和TreeSet一致,1通过自然排序(Comparable接口),2定制排序(Compartor比较器)
- 存储方式(底层实现方式)
hash表+链表(红黑树【1.8】)
它和我们在设计链表结构linkedList非常相像。基于链表结构封装成容器类,那我们是怎样存储的? |
把值封装成一个对象,并且里面有其他字段。
Map的存储原理也是类似:利用封装的,如果要封装,首先有个类型,这个类型是Entry,
Entry类型作用:Entry用来封装用户添加的一对数据.Entry类型有两个字段,添加的时候,使用Entry把两个值封装成一个对象,然后放到Map容器里面。对于Map而言,看到的只有Entry对象。
由于Entry的存在,只是对于Map来讲才有意义. 因此它使用封装,把Entry类型设计到Map里面。相当于内部类。
Map 里面的方法: |
entrySet() 返回Set,(返回当前Map中所有的entry对象,使用Set存储起来。)
keySet() 返回Map当中所有的key,存储到一个Set集合当中。
values() 返回所有的values,存储到一个Collection。
get(Object key) 返回Collection,通过key查找对应的值。
这里get方法为什么返回Collection? |
因为values 有重复,如果返回Set,就不能含有重复的元素
- Map的两种遍历方式
- entrySet
// Set<Map.Entry<K,V>> entrySet() 返回此映射中包含的映射关系的 Set 视图。
Set entrySet = map.entrySet();
for (Object object : entrySet) {
Entry e = (Entry)object;
System.out.println(e.getKey() +"---" +e.getValue());
}
- keySet
//Set<K> keySet() 返回此映射中包含的键的 Set 视图。
Set keySet = map.keySet();
for (Object object : keySet) {
System.out.println(object+"--"+map.get(object));
}