JavaSE 集合
Posted ITWEL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaSE 集合相关的知识,希望对你有一定的参考价值。
体系一:Collection
(一)基本介绍
I. 是一个集合接口,提供了对集合对象进行基本操作的通用接口方法。
II. 使用前需要导入java.util.Collection包
说明:
collection接口中定义了很多抽象方法,是一个抽象接口,无法进行实例化
(二)具体分类
Collection接口是抽象的,List接口和Set接口继承了Collection
二者分别在Collection接口的基础上定义了自己特有的抽象方法,应用于不同的使用场景。
List接口:存储有序的、可重复的数据。---->动态数组
|---ArrayList 、 LinkedList 、Vector
Set接口:存储无序的、不可重复的数据。 ---->数学中“集合”
|---HashSet 、LinkedHashSet、TreeSet
理解:有序的与无序的??
有序:指的是再存储数据时按照数组的物理地址顺序存储。
无序:指的是存储数据时并不按照顺序存储(可能会按照哈希值来进行存储)。
(三)具体使用
I.Collection
常用方法如下:
说明:此处以实现类ArrayList为例
(1)add(Object obj):将对象obj添加到集合中
说明:向Collection接口的实现类中添加数据obj时,要求obj所在类重写equals()·
(2)size():获取添加元素的个数
(3)addAll(Collection coll):将coll中的元素添加到当前的集合中
(4)clear():清空当前集合中的元素
(5)isEmpty():判断当前集合是否为空
(6)contains(Object obj):判断obj是否存在于当前集合中
说明:对于自定义的类,如果不进行重写equals()方法,就不会根据对象的内容进行判断(会默认使用 “==”判断),比如String类中就重写了equals()方法来进行比较内容。
(7)containAll(Collection coll):判断coll集合中的元素是否全部存在于当前集合中。
(8)remove(Object obj):从当前集合中移除obj元素
(9)removeAll(Collection coll):从当前集合中移除coll中的与其有交集的 元素(差集)
(10)retainAll(Collection):获取当前集合和coll集合的交集,并返回给当前集合。
(11)equals(Object obj):判断当前集合和形参集合的元素是否都相同
说明:在比较时是按集合中元素的添加顺序一个一个比较的,如果添加顺序不同,返回的就是false
(12)hashCode():返回当前对象的哈希值
(13)toArray():将集合转化为数组
(14)Arrays.asList(arr):将数组转化集合
注意:
(15)iterator():返回Iterator接口的实例,用于遍历集合元素
原理分析:
说明:
(1)集合元素的遍历操作,使用迭代器Iterator接口,主要使用
hasNext()方法和next()方法
(2)内部定义了remove()方法,可以在遍历的时候,删除集合中的元素。
如果还未调用next()或在上一次调用next()方法之后已经调用remove ()方 法,再次调用remove都会报IllegalStateException错误
错误使用方式:
II.Arraylist(Vector、LinkedList)
①比较
相同点:三个类都实现了List接口,存储数据的特点相同(存储有序地、可重复的)元 素.
不同点:
(1)ArrayList底层存储类型是Object数组,而LinkedList底层是双向链表
(2)ArrayList和Vector调用创建空参构造器创建对象时,默认的size是10.
但是当自动扩容的时候,ArrayList扩容为当前容器size的1.5倍,而
Vector自动扩容为当前的2倍。
使用场景:
(1)当查找操作比较多时,使用ArrayList,因为底层是数组实现,可以根据下标查 找,时间复杂度是O(1),而LinkedList底层是双向链表,查找起来还要遍 历,其时间复杂度是O(n)
(2) 当插入、删除操作比较多时,使用LinkedList,其中只需要修改pre和last指针 即可,时间复杂度为O(1),
而ArrayList还要进行遍历数组,时间复杂度为O(n)
说明:Vector是一个List接口的一个古老实现类,一般不使用,在实际应用时常用 ArrayList(主要实现类)
Vector: 1.0版本 LinkedList、ArrayList: 1.2版本
②常用方法
(1)add(int index,Object ele):在集合中的指定位置(index)插入元素(ele)
说明:集合中的索引位置和数组是一样,均是从零开始的
(2)addAll(int index,Collection eles):从index开始插入集合eles
(3)get(int index):获取指定索引位置的元素
(4)indexOf(Object obj):返回obj在集合中第一次出现位置,如果不存在的话返回-1
(5)lastIndexOf(Object obj) :从后往前遍历第一次出现obj的位置,如果不存在就返回-1
(6)remove(int index):移除集合中特定位置的元素
(7)set(int index,Object eles):设置指定位置(index)为指定元素(eles)
(8)subList(int fromIndex,int toIndex):返回从fromIndex到toIndex的子集合(左闭右开)
③总结
实现类实现了Collection中的方法,可以通过具体实现类对象进行调
III.HashSet(LinkedHashSet、TreeSet)
HashSet:作为Set接口的主要实现类,线程不安全,可以存储null值
LinkedHashSet:作为HashSet的子类,遍历其内部数据时,可以按照添 加的顺序进行遍历
TreeSet:可以按照添加对象的指定属性进行排序
对比分析:
LinkedHashSet作为HashSet的子类,在添加数据的同时,每个数据还维护了两个引用,记录此数据前一个数据和后一个数据,对于频繁的遍历操作,LinkedHashSet效率高于HashSet
说明:
Set接口中没有额外定义新的方法,使用的都是Collection中声明过的方法
(1)无序性:不等于随机性。存储的数据在底层中并非按照数组的索引顺序进行添加,而是根据数据的哈希值进行添加。
(2)不可重复性:保证添加的元素按照equals()判断时,不能返回true.即相同的元素只能添加一个。
补充:再向HashSet中添加元素a,首先调用元素a所在类中的HashCode()方法,计算元素a的值,此哈希值接着通过某种算法计算出在HashSet底层数组中的存放位置(即为索引位置),判断数组在此位置上是否已经有元素
数组在此位置上是否已经有元素:
如果此位置上没有其他元素,则元素a添加成功 --->情况1
如果此位置上有其他元素b(或是以链表形式存在的多个元素),则比较元素a与 元素b的hash值
如果hash值不相同,则元素a添加成功 ---->情况2
如果hash值相同,进而需要调用元素a所在类的equals方法:
equal()返回true,添加a失败
equal()返回false,则元素a添加成功 ----->情况3 说明:对于添加成功的情况2或情况3而言:元素a与已经存在指定位置上的数据
以链表的方式进行存储 。
jdk7:元素a放到数组中,指向原来的元素
jdk8:原来的元素在数组中,指向元素a
总结:七上八下
使用注意:
①向Set中添加数据时,其所在的类一定要重写hashCode()和equals()
②重写的·hashCode()和equals()尽可能保持一致性:
相等的对象必须有相等的散列码
小技巧:对象用作equals()方法比较的Field,都应该用来计算hashCode值
使用说明(TreeSet)
①向TreeSet中添加的数据,要求是相同类的对象
compareTo()方法
自然排序:在自定义类中实现Compare接口,重写compareTo()方法
说明:在重写方法时尽量将所有属性都比较一下
定制排序:通过创建Comparator对象,然后再重写compare()方法
(四) 核心意义
为各种具体集合提供了最大化的统一操作方式。
体系二:Map
(一)基本介绍
I.双列集合,用来存储键值对<key ,value>
说明:
(1)key所在的类需要重写equals()和hashCode()方法
(2)value所在的类要重写equals()方法
(二)具体分类
Map:双列数据,存储key-value对的数据, ----类似于高中的函数:y=f(x)
|--HashMap:作为Map的主要实现类,线程不安全,效率高,可以存储 为 null的key和value
|--LinkedHashMap:保证在遍历map元素时,可以按照添加 的顺序实现遍历。
原因:在原有的HashMap底层结构基础上,添加了一对指针,
指向前一个和后一个元素。(对于频繁的遍历操作效率更高)
|--TreeMap:保证按照添加的key--value对进行排序,实现排序遍历
此时考虑key的自然排序或定制排序。
底层:红黑树
|--Hashtable:作为古老的实现类,线程安全的,效率低,不能存储 为null的key和value
|--Properties:常用来处理配置文件。
key和value都是String类型
HashMap底层:
数组+链表(jdk7之前)
数组+链表+红黑树(jdk8)
HashMap
常见参数:
①DEFAULT_INITIAL_CAPACITY:HashMap的默认容量-->16
②DEFAULT_LOAD_FACTOR:HashMap的默认加载因子
③threshold:扩容的临界值,等于(容量填充因子):16*0.75=>12
④TREEIFY_THRESHOLD:Bucket中链表长度大于该默认值,转为红黑树:8
⑤MIN_TREEIFY_CAPACITY:桶中的Node被树化时最小的hash表容量:6
相关源码:
(1)put(key,value):添加元素(先进行比较,后进行添加)
(2)addEntry(int hash,K key,V value,int bucketIndex):
分析:
(1)过程一:调用key所在的hashCode()计算key1的哈希值,此哈希值经过某种 算法计算以后,得到Entry数组中的存放位置
(2)过程二:
如果此位置上的数据为空,此时的key1-value1添加成功 ----情况1
如果此位置上的数据不为空(意味着此位置上存在一个或多个数据<以链表的形 式存在>),比较key1与已经存在的一个或多个数据的哈希值
如果key1的哈希值与已经存在的数据的哈希值都不相同,此时key1--value1 添加成功---情况2
如果key的哈希值和已经存在的某一个数据(key2--value2)的哈希值相同, 继续比较,调用key所在类中的equals(key)
如果equals()返回false:此时的key--value条件成功 --情况3
如果equals()返回true:使用value1,替换value2
补充:
关于情况1和·情况2,此时key1--value1和原来的数据以链表的形式存储
扩容情况:
jdk7 :扩容为原来容器容量的2倍
jdk8 :扩容为原来容器容量的1.5倍
jdk8相较于jdk7在底层实现方面的不同:
(1)new HashMap():底层并没有创建一个长度为16的数组
(2)jdk8底层的数组是:Node[],而非Entry[]
(3) 首次调用put()方法时,底层创建长度为16的数组
(4)jdk7底层结构只有:数组+链表 jdk8底层结构为:数组+链表+红黑树
当数组的一个索引位置上的元素以链表的形式存在的数据个数>8并且当前数组 的长度>64时,此时索引位置上的所有数据改为使用红黑树进行存储。
说明:
并不是容量全部用完的时候才进行扩容,而是满足如上条件后才可以进行扩容。
(三)具体使用
使用演示:
(1)put(Object key,Object value):添加元素
(2)putAll(Map m):将m中的所有键值对存放到当前map中
(3)remove(Object key):移除掉指定key的key-value对,并返回value
(4)clear():清空当前map中的所有数据
(5)get(Object key):获取指定key对应的value
(6)containsKey(Object key):是否包含指定的key
(7)containsValue(Object value):是否包含指定的value
(8)size():返回key--value键值对的个数
(9)isEmpty():判断当前map是否为空
(10)equals(Object obj):判断当前map与对象obj是否相等
(11)Set keySet():返回所有key构成的·Set集合
(12)Collection values():返回所有的value构成的Collection集合
(13)Set entrySet():返回所有key--value对构成的Set集合
总结:
增加:
删除:remove(Object key)
修改:put(Object key,Object values)
查询:get(Object key)
遍历:keySet()/values()/entrySet()
长度:size()
properies:
- 首先在工程下创建一个properties文件
- 方式一:在工程上右键点击new-->file-->命名为jdbc.properties
- 方式二:在工程上右键点击new-->Resource Bundle-->输入jdbc,就可以了
- 在文件中加入数据,然后在主程序中进行读取文件中的内容
使用具体
Collections
定义:是一个操作Collection、Map的一个工具类。
常用方法:
reverse(List):反转 List 中元素的顺序
shuffle(List):对 List 集合元素进行随机排序
sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序
sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换
Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回 给定集合中的 最大元素
Object min(Collection)
Object min(Collection,Comparator)
int frequency(Collection,Object):返回指定集合中指定元素的出现次数
void copy(List dest,List src):将src中的内容复制到dest中
boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的 所有旧值
copy()方法(易错)
以上是关于JavaSE 集合的主要内容,如果未能解决你的问题,请参考以下文章
JavaSE_集合(集合简单认识CollectionList)
JavaSE-14.2.1List集合的特点特有方法遍历方式
JavaSE8基础 Arrays.sort 一维int数组中指定范围中的成员进行升序排列
JavaSE学习总结(十三)Set集合HashSet集合LinkedHashSet集合TreeSet集合比较器的使用利用Set集合实现去重