数组VS集合
数组(长度开始时必须指定,而且一旦指定,不能更改)(增加/删除元素比较麻烦)
1) 2)保存的必须为同一类型的元素
3)使用数组进行
集合(动态保存任意多个对象)(增加/删除元素比较方便)
1)可以,使用比较方便!
2)提供了一系列方便的操作对象的方法:add、remove、set、get等
3)使用集合添加/删除新元素很简洁
集合的框架体系
List 接口、Set接口 ( 他们的实现子类都是)
Map 接口(实现子类是)
线程安全不安全介绍
线程不安全
ArrayList, LinkedList,
HashSet, LinkedHashSet,TreeSet
HashMap , LinkedHashMap,TreeMap
线程安全
内置
并发包
CopyOnWriteArrayList
CopyOnWriteArraySet
ConcurrentHashMap
通过包装
Collections.synchronizedList
Collections.synchronizedSet
Collections.synchronizedMap
Collection 接口和常用方法
Collection 接口实现类的特点
Collection 接口常用方法,以实现子类 ArrayList 来演示
增 add,addAll
删 remove(元素|或下标)
查 contains
大小容量 size,isEmpty
清空 clear
Collection 接口遍历元素方式 1 使用 Iterator(迭代器) (lterator 仅用于遍历集合,)(。若不调用,且下一条记录无效,直接调用it.next()会抛出NoSuchElementException异常)
1)lterator对象称为选代器,。
2)所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了lterator接口的对象,即。
4)lterator 仅用于遍历集合,
提示:在调用iterator.next()方法之前必须要调用iterator.hasNext()进行检测。
Collection 接口遍历对象方式 2 for 循环增强()
List 接口和常用方法(,支持添加null,支持索引)(只能通过set方法进行修改)(下列所有方法对其实现类通用)
1)List集合类中元素(即添加顺序和取出顺序一致)、且 2)List集合中的每个元素都有其对应的顺序索引,即。
零基础快速学会java
增,boolean 、void 、boolean (int index, Collection eles):从 index 位置开始将 eles 中的所有元素添加进来
删,Object :移除指定 index 位置的元素,,boolean ;
改,Object (int index, Object ele):设置指定 index 位置的元素为 ele , 相当于是替换.
查,Object (int index):获取指定 index 位置的元素;int (Object obj):返回 obj 在集合中首次出现的位置,int lastIndexOf(Object obj):返回 obj 在当前集合中末次出现的位置
插,void
截取,List (int fromIndex, int toIndex):返回从 fromIndex 到 toIndex 位置的子集合 [fromIndex,toIndex)
其他 , Collection 接口中的方法
三种遍历方式(1.使用iterator 2.使用增强for 3.使用普通for)
ArrayList 底层结构和源码分析(由数组来实现数据存储的)(ArrayList 基本等同于Vector,但是其)(无参 0,10,1.5倍)(有参 指定,1.5倍)
- ArrayList中.
ArrayList 实现了 Serializable 接口,所以它本身是可以序列化的,但ArrayList 的设计者选择将这个数组声明为 transient,这样在序列化时不会直接序列化整个数组,而是通过自定义的方法只序列化实际存储的元素,这样 transient Object[l elementData; //transient 表示瞬间,短暂的,表示 - 当创建ArrayList对象时,如果使用的是无参构造器,则,,如需要再次扩容,则。
- 如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容则直接扩容elementData为1.5倍。
Vector(用的少) 底层结构和源码分析(底层也是一个对象数组)(线程同步的,线程安全)(无参 10,2倍)(有参 指定,2倍)
- Vector类的定义说明
- ,
- Vector 是,
- 当创建Vector对象时,如果使用的是无参构造器,则,如需要扩容,则。
- 如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容则直接扩容elementData为2倍。
LinkedList 底层结构和源码分析(,而且维护了两个属性first和last分别指向首节点和尾节点,添加和删除效率较高)((没有同步机制))
- LinkedList
- LinkedList中维护了两个属性first和last分别指向 首节点和尾节点
- 每个节点(Node对象),里面又维护了,其中通过prev指向前一个,通过next指向后一个节点。最终实现双向链表.
- 所以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高
模拟一个简单的双向链表
Set 接口和常用方法(,支持添加null( TreeSet 需要对元素进行排序,不能存储null),)(注意:添加的顺序和取出的顺序不一致,)(下列所有方法对其实现类通用)
和 List 接口一样, Set 接口也是 Collection 的子接口,因此,常用方法和 Collection 接口一样
增,boolean 、、boolean (Collection eles):将 eles 中的所有元素添加进来
删,boolean ;
其他 Collection 接口中的方法
两种遍历方式(1.使用iterator 2.使用增强for )()
HashSet 底层结构和源码分析(HashSet实际上是HashMap,HashMap底层是(数组+链表/红黑树))(0,16(看阈值,为其0.75,实际12时候要扩容),2倍)(与hashCode() 和 equals() 息息相关)(O(1))
添加元素原理(附面试题)
- 添加一个元素时,先得到 一会转成->
- 找到存储数据表table,看这个索引位置是否已经存放的有元素
- 如果没有,直接加入
- 如果有 , 调用 equals 比较逐个比较,如果有相同,就放弃添加,全部比较完都不相同,则添加到最后
经典面试问题:字符串加入 HashSet(String 类已经重写了 hashCode() 和 equals() 方法,两个内容相同的字符串对象被认为是相等的)
String 类已经重写了 hashCode() 和 equals() 方法,两个内容相同的字符串对象被认为是相等的。因此,虽然两个 String 对象是不同的实例,但由于它们的值相同,所以第二次添加 “hsp” 时,HashSet 判断它已经存在,因此不会再次添加。
扩容机制(太大了转化成红黑树)
- HashSet底层是HashMap,,临界值(threshold)是 16*加载因子(loadFactor)是0.75 =12
- 如果table 数组使用到了临界值 12,就会扩容到 162 =32,新的临界值就是32*0.75 =24,依次类推
转成红黑树机制
注意:在Java8中,如果 TREEIFY _THRESHOLD(), >=MIN_TREEIFY_CAPACITY()就会进行树化(红黑树),否则仍然采用数组扩容机制
LinkedHashSet(是 HashSet 的子类)底层结构和源码分析(底层是一个 LinkedHashMap,底层维护了一个 )(O(1))(有序,因为其多维护了一个和其插入顺序有关的双向链表)
TreeSet底层结构和源码分析(底层是一个 TreeMap,底层维护了一个 )(O(logn))( TreeSet 需要对元素进行排序,)
Map 接口和常用方法(key 不允许重复(当有相同的 k , 就等价于替换), value 可以重复)(key 和 value 之间存在单向一对一关系)(常用String类作为Map的 key)
增,(key,value)
删,V (Object key):移除指定键key的元素,
改,(key,value),修改键为key的元素
查,V (Object key):获取键为key的value值;V (Object key, V defaultValue) ;boolean (Object key);判断键key是否存在;:获取所有的键;:获取所有的值;:获取所有关系k-v(Set<Map.Entry<K, V>> entrySet();需要向下类型转化为Map.Entry)
大小容量 size,isEmpty
清空 clear
两种遍历方式(1.使用iterator 2.使用增强for)
HashMap 底层结构和源码分析(不保证映射的顺序,因为底层是以hash表的方式来存储的)(jdk7的hashMap 底层 数组+链表,jdk8的hashMap 底层 数组+链表/红黑树)(线程不安全自,方法没有做同步互斥的操作,没有synchronized)(注意:只有冲突较多的链表才会被转换为红黑树`,而不是整个 HashMap)(扩容机制等见HashSet)
- HashMap底层维护了,
- 当添加key-val时,通过key的哈希值(hashcode)得到在table的索引。然后判断该索引处是否有元素,如果没有元素直接添加。如果该索引处有元素(链表/红黑树),继续判断该元素的key和准备加入的key相是否相等(equals),如果相等,则直接替换val;如果不相等需要判断是树结构还是链表结构,做出相应处理。如果添加时发现容量不够,则需要扩容。
LinkedHashMap(是 HashMap 的子类)底层结构和源码分析(底层维护了一个 )(O(1))(有序,因为其多维护了一个和其插入顺序有关的双向链表)
TreeMap 底层结构和源码分析(底层维护了一个 )(O(logn))( TreeSet 需要对元素进行排序,)
HashTable 底层结构和源码分析()(线程安全的synchronized)
Properties(是 HashTable 的子类) 底层结构和源码分析(还可以用于 从 xxx.properties 文件中,加载数据到Properties类对象,并进行读取和修改)
开发中如何选择集合实现类(记住)
- 先判断存储的类型(一组对象[单列]或一组键值对[双列])
- 一组对象[单列]:Collection接口
- 允许重复:List
增删多:LinkedList[底层维护了一个双向链表]
改查多:ArrayList[底层维护 Object类型的可变数组] - 不允许重复:Set
无序:HashSet[底层是HashMap ,维护了一个哈希表 即(数组+链表+红黑树)]
有序:LinkedHashSet,维护数组+双向链表
排序:TreeSet
- 一组键值对[双列]:Map
- 键无序:HashMap[底层是:哈希表 jdk7:数组+链表,jdk8: 数组+链表+红黑树]
- 键有序:LinkedHashMap
- 键排序:TreeMap
- 读取文件:Properties
Collections ()(里面的方法均为static 方法)
排序, sort(List);sort(List,Comparator)
翻转, reverse
指定元素的出现次数 ,frequency(Collection,Object)
交换, swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换
最大/小元素, max(Collection);max(Collection,Comparator)
复制,copy(List dest,List src)
替换,replaceAll(List list,Object oldVal,Object newVal)
本章练习题
1. 放入TreeSet里面的元素一定是可以比较的(内部通过比较来确保元素的顺序和去重,因此无法比较的元素会导致ClassCastException异常)
2.HashSet里面放入对象的常见陷阱
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/h6javajc/19310.html