1、数组和集合的元素存储的个数问题。
- 数组定义后类型确定,长度固定
- 集合类型可以不固定,大小是可变的。
2、数组和集合存储元素的类型问题。
- 数组可以存储基本类型和引用类型的数据。
- 集合只能存储引用数据类型的数据。
3、数组和集合适合的场景
Set系列集合:添加的元素是无序、不重复、无索引。
- HashSet: 无序、不重复、无索引;LinkedHashSet: 有序、不重复、无索引。
-
2.集合对于泛型的支持
集合都是支持泛型的,可以在编译阶段约束集合只能操作某种数据类型
注意:集合和泛型都只能支持引用数据类型,不支持基本数据类型,所以集合中存储的元素都认为是对象。3.Collection集合
Collection是单列集合的祖宗接口,它的功能是全部单列集合都可以继承使用的。
常用API
方法名称 | 说明 |
---|---|
public boolean add(E e) | 把给定的对象添加到当前集合中 |
public void clear() | 清空集合中所有的元素 |
public boolean remove(E e) | 把给定的对象在当前集合中删除 |
public boolean contains(Object obj) | 判断当前集合中是否包含给定的对象 |
public boolean isEmpty() | 判断当前集合是否为空 |
public int size() | 返回集合中元素的个数。 |
public Object[] toArray() | 把集合中的元素,存储到数组中 |
1.迭代器
- 遍历就是一个一个的把容器中的元素访问一遍。
- 迭代器在Java中的代表是Iterator,迭代器是集合的专用遍历方式。
| 方法名称 | 说明 |
| —- | —- |
| Iterator
iterator() | 返回集合中的迭代器对象,该迭代器对象默认指向当前集合的0索引 | | booleanhasNext() | 询问当前位置是否有元素存在,存在返回true ,不存在返回false | | E next() | 获取当前位置的元素,并同时将迭代器对象移向下一个位置,注意防止取出越界。 |
1、迭代器的默认位置在哪里。
Iterator
2、迭代器如果取元素越界会出现什么问题。
会出现NoSuchElementException异常。
2.数据结构
各种数据结构的特点和作用是什么样的
队列:先进先出,后进后出。
栈:后进先出,先进后出。
数组:内存连续区域,查询快,增删慢。
链表:元素是游离的,查询慢,首尾操作极快。
二叉树:永远只有一个根节点, 每个结点不超过2个子节点的树。
查找二叉树:小的左边,大的右边,但是可能树很高,查询性能变差。
平衡查找二叉树:让树的高度差不大于1,增删改查都提高了。
红黑树(就是基于红黑规则实现了自平衡的排序二叉树)
3.List集合
- ArrayList、LinekdList :有序,可重复,有索引。
- 有序:存储和取出的元素顺序一致
- 有索引:可以通过索引操作元素
- 可重复:存储的元素可以重复
List集合因为支持索引,所以多了很多索引操作的独特api,其他Collection的功能List也都继承了。
方法名称 | 说明 |
---|---|
void add(int index,E element) | 在此集合中的指定位置插入指定的元素 |
E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
E set(int index,E element) | 修改指定索引处的元素,返回被修改的元素 |
E get(int index) | 返回指定索引处的元素 |
1、List系列集合特点
- ArrayList、LinekdList :有序,可重复,有索引。
2、List的实现类的底层原理
- ArrayList底层是基于数组实现的,根据查询元素快,增删相对慢。
LinkedList底层基于双链表实现的,查询元素慢,增删首尾元素是非常快的。
1.ArrayList集合底层原理
ArrayList底层是基于数组实现的:根据索引定位元素快,增删需要做元素的移位操作。
第一次创建集合并添加第一个元素的时候,在底层创建一个默认长度为10的数组。
2.LinkedList的特点
底层数据结构是双链表,查询慢,首尾操作的速度是极快的,所以多了很多首尾操作的特有API。 | 方法名称 | 说明 | | —- | —- | | public void addFirst(E e) | 在该列表开头插入指定的元素 | | public void addLast(E e) | 将指定的元素追加到此列表的末尾 | | public E getFirst() | 返回此列表中的第一个元素 | | public E getLast() | 返回此列表中的最后一个元素 | | public E removeFirst() | 从此列表中删除并返回第一个元素 | | public E removeLast() | 从此列表中删除并返回最后一个元素 |
当我们从集合中找出某个元素并删除的时候可能出现一种并发修改异常问题。
存在问题
- 迭代器遍历集合且直接用集合删除元素的时候可能出现。
- 增强for循环遍历集合且直接用集合删除元素的时候可能出现。
没有问题
- 迭代器遍历集合但是用迭代器自己的删除方法操作可以解决。
- 使用for循环遍历并删除元素不会存在这个问题。可以倒序删除,也可以每删除一个自减一。
4.SET
Set系列集合特点
- 无序:存取顺序不一致
- 不重复:可以去除重复
- 无索引:没有带索引的方法,所以不能使用普通for循环遍历,也不能通过索引来获取元素。
Set集合实现类特点
- HashSet : 无序、不重复、无索引。
- LinkedHashSet:有序、不重复、无索引。
-
1.HashSet底层原理
HashSet集合底层采取哈希表存储的数据。
哈希表是一种对于增删改查数据性能都较好的结构。
去重要重写对象的hashCode和equals方法。2.LinkedHashSet集合概述和特点
有序、不重复、无索引。
- 这里的有序指的是保证存储和取出的元素顺序一致
原理:底层数据结构是依然哈希表,只是每个元素又额外的多了一个双链表的机制记录存储的顺序。
3.TreeSet集合概述和特点
不重复、无索引、可排序
- 可排序:按照元素的大小默认升序(有小到大)排序。
- TreeSet集合底层是基于红黑树的数据结构实现排序的,增删改查性能都较好。
- 注意:TreeSet集合是一定要排序的,可以将元素按照指定的规则进行排序。
①TreeSet集合默认的规则
- 对于数值类型:Integer , Double,官方默认按照大小进行升序排序。
- 对于字符串类型:默认按照首字符的编号升序排序。
对于自定义类型如Student对象,TreeSet无法直接排序。
②自定义排序规则
让自定义的类(如学生类)实现Comparable接口重写里面的compareTo方法来定制比较规则。
TreeSet集合有参数构造器,可以设置Comparator接口对应的比较器对象,来定制比较规则。
4.哈希表
①组成
JDK8之前的,底层使用数组+链表组成
DK8开始后,底层采用数组+链表+红黑树组成。②哈希值
是JDK根据对象的地址,按照某种规则算出来的int类型的数值。
③获取哈希值API
public int hashCode():返回对象的哈希值
④特点
同一个对象多次调用hashCode()方法返回的哈希值是相同的
默认情况下,不同对象的哈希值是不同的。⑤Set集合哈希表的底层原理
JDK8之前的,哈希表:底层使用数组+链表组成
JDK8开始后,哈希表:底层采用数组+链表+红黑树组成。⑥哈希表的详细流程
创建一个默认长度16,默认加载因为0.75的数组,数组名table
- 根据元素的哈希值跟数组的长度计算出应存入的位置
- 判断当前位置是否为null,如果是null直接存入,如果位置不为null,表示有元素, 则调用equals方法比较属性值,如果一样,则不存,如果不一样,则存入数组。
- 当数组存满到16*0.75=12时,就自动扩容,每次扩容原先的两倍
4.Map
1.Map集合概述和使用
- Map集合是一种双列集合,每个元素包含两个数据。
- Map集合的每个元素的格式:key=value(键值对元素)。
- Map集合也被称为“键值对集合”。
- Map集合的完整格式:{key1=value1 , key2=value2 , key3=value3 , …}
2.Map集合的特点
- Map集合的特点都是由键决定的。
- Map集合的键是无序,不重复的,无索引的,值不做要求(可以重复)。
- Map集合后面重复的键对应的值会覆盖前面重复键的值。
- Map集合的键值对都可以为null。
HashMap:元素按照键是无序,不重复,无索引,值不做要求。(与Map体系一致)
LinkedHashMap:元素按照键是有序,不重复,无索引,值不做要求。
TreeMap:元素按照建是排序,不重复,无索引的,值不做要求。
方法名称 | 说明 |
---|---|
V put(K key,V value) | 添加元素 |
V remove(Object key) | 根据键删除键值对元素 |
void clear() | 移除所有的键值对元素 |
booleancontainsKey(Object key) | 判断集合是否包含指定的键 |
booleancontainsValue(Object value) | 判断集合是否包含指定的值 |
booleanisEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中键值对的个数 |
//获取全部键的集合:public Set<K> keySet()
Set<String> keys = maps.keySet();
System.out.println(keys);
//获取全部值的集合:Collection<V> values();
Collection<Integer> values = maps.values();
System.out.println(values);
3.Map集合的遍历
方式一:键找值的方式遍历:先获取Map集合全部的键,再根据遍历键找值。
//键找值:第一步:先拿到集合的全部键。
Set<String> keys = maps.keySet();
System.out.println(keys);
// 2、第二步:遍历每个键,根据键提取值
for (String key : keys) {
int value = maps.get(key);
System.out.println(key + "===>" + value);
}
方式二:键值对的方式遍历,把“键值对“看成一个整体,难度较大。
// 1、把Map集合转换成Set集合
Set<Map.Entry<String, Integer>> entries = maps.entrySet();
// 2、开始遍历
for(Map.Entry<String, Integer> entry : entries){
String key = entry.getKey();
int value = entry.getValue();
System.out.println(key + "====>" + value);
}
方式三:JDK 1.8开始之后的新技术:Lambda表达式。
maps.forEach(new BiConsumer<String, Integer>() {
@Override
public void accept(String k, Integer v) {
System.out.println(k+"----->"+v);
}
});
//简化
maps.forEach((k, v) -> System.out.println(k + "--->" + v));
4.HashMap的特点
- HashMap是Map里面的一个实现类。特点都是由键决定的:无序、不重复、无索引
- 没有额外需要学习的特有方法,直接使用Map里面的方法就可以了。
HashMap跟HashSet底层原理是一模一样的,都是哈希表结构,只是HashMap的每个元素包含两个值而已
5.LinkedHashMap集合概述和特点
由键决定:有序、不重复、无索引。
- 这里的有序指的是保证存储和取出的元素顺序一致
原理:底层数据结构是依然哈希表,只是每个键值对元素又额外的多了一个双链表的机制记录存储的顺序。
6.TreeMap集合概述和特点
由键决定特性:不重复、无索引、可排序
- 可排序:按照键数据的大小默认升序(有小到大)排序。只能对键排序。
- 注意:TreeMap集合是一定要排序的,可以默认排序,也可以将键按照指定的规则进行排序
- TreeMap跟TreeSet一样底层原理是一样的。