Java集合
一、java集合
Java集合可分为Collection和Map两种体系
- Collection接口:单列数据,定义了存取一组对象的方法的集合
- List:元素有序、可重复的集合
- Set:元素无序、不可重复的集合 - Map接口:双列数据,保留具有映射关系“key-value”的集合。
注意
List都可以存null
HashMap可以存储一个key为null,
TreeMap不能存null,
Set底层Map,
所以HashSet可以有1个位null的元素,
TreeSet也不能存储null
二、Collection接口
Collection接口
- 是List、set和Queue接口的父接口。
- JDK不提供其具体实现,而是提供Collection的List、Set具体子接口
- java5之前,java集合会丢失容器中数据类型,当成Object处理,出现泛型后,可以记住类型。
- 继承了java.lang.Iterator接口,有iterator方法
方法
add、addAll、clear、isEmpty、contains(Object obj)是否同一元素、containsAll(Collection c)比较两个集合元素、remove(ele)只删除找到的第一个、retainAll(collection)取交集存放当前集合、iterator遍历、hashCode、toArray
Iterator接口
- Iterator对象称为迭代器(设计模式一种)
- 迭代器模式:提供一种方法访问一个容器对象中各个元素,而又不暴露该对象内部细节。
- 迭代器模式,就是为容器而生。类似“售票员、空姐”
- 集合每次调用iterator()方法都会得到一个全新的对象。默认游标在第一个元素。
- 方法:hasNext、next、remove
- 未调用next就使用remove会报IIIegalStateException
1.List接口
List:有序集合(序列),用户可以精确控制列表中每个元素的插入位置
与set不同:允许重复
特点:
- 有索引
- 可以存储重复元素
- 元素存取有序
子类延伸
ArrayList、LinkedList、vector
-
ArrayList集合:底层是数组结构实现,查询快,增删慢;
-
LinkedList集合:底层是链表结构实现,增删快,查询慢;
方法:List添加了根据索引来操作集合方法
- add(index,ele)在index位置加入ele元素
- add(index,collection):在index位置开始将collection元素加入
- get(index):返回指定索引元素
- indexOf(obj):返回obj在结合首次出现位置
- lastIndexOf(obj):返回obj在集合中末次出现位置
- remove(index):移除index位置的元素
- set(index,ele):设置index位置元素为ele
- subList(fromIndex,toIndex):返回从fromindex到toIndex位置子集合
1.ArrayList
ArrayList是List接口的典型实现
- 本质上,ArrayList是对象引用的一个“变长”数组
- ArrayList在JDK7.0与8.0区别?
- JDK7.0:饿汉式,直接创建一个初始容量为10的数组
- JDK8.0:懒汉式,开始创建长度为0的数组,添加第一个元素时再创建初始容量为10的数组
- Arrays.asList(…)返回List集合,既不是ArrayList也不是Vector。是一个固定长度的List集合
1.ArrayList嵌套HashMap:用来存放。按类的map
2.HashMap嵌套ArrayList:用来存一个对应多个的情况;
2.LinkedList
LinkedList:对于频繁的插入或删除元素的操作,建议LinkedList,效率高
新增方法
- addFirst、addLast(obj)
- getFirst、getLast
- removeFirst、removeLast
LinkedList:双向链表,内部没有声明数组,而是定义了Node类型的first和last,用于记录首末元素。同时,定义内部类Node,作为LinkedList中保存数据的基本结构。Node除了保存数据,还定义两个变量:
- prev变量记录前一个元素位置
- next变量记录下一个元素位置
3.Vector
Vector是一个古老的集合,jdk1.0就有,与ArrayList类似,区别在于Vector是线程安全的
- 在各种list中,最好把ArrayList当缺省选择。当插入、删除频繁用LinkedList;Vector总是比ArrayList慢,所以避免使用。
新增方法
addElement(obj)、insertElementAt(obj,index)、setElementAt(obj,index)、removeElement(obj)、removeAllElements()
4.以上三者异同,ArrayList扩容机制
2.Set接口
Set接口
- set接口没有提供额外的方法
- set不允许包含相同的元素,如果两个相同的元素加入Set集合会失败
- 使用equals判断
特点
- 元素存取无序
- 没索引,智能通过迭代器或者增强for遍历
- 不能存储重复值
哈希值
-
是jdk根据对象的的地址或者字符串或者数字算出来的int类型值
-
object中的hashCode,返回对象的哈希值
特点:
- 同一个对象多次调用hashCode()方法返回的哈希值是相同的
- 默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同
1.HashSet
HashSet
- HashSet是按Hash算法来存储集合中的元素,因此具有很好的存取、查找、删除性能
HashSet特点
- 不能保证元素的排列顺序
- HashSet不是线程安全
- 集合元素可以是null
HashSet集合判断两个元素相等的标准:
两对象通过hashCode()方法比较相等,并且量对象的equals返回值相同
- 对于存放在Set容器的对象,对应类一定重写equals()和hashCode()方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”
HashSet添加过程
当添加元素时,会先调用对象的hashCode方法得到hashCode,如果两个元素的hashCode相同,继续调用equals,返回为true则添加失败,为false,保存该元素,但该数组位置已经有元素,此时通过链表方式继续添加;如果两个hashCode不同,也会保存该元素,保存在不同数组位置。
扩容机制
底层是数组,初始为16,当使用率到达0.75,即16*0.75=12,就会扩大容量为原来的2倍。(16->32,32->64)
重写hashCode原则
- 程序运行时,同一对象多次调用hashCode返回值相同
- 当两个对象的equals返回值相同返回hash值相同
= 对象中用作equals方法比较Field,都应用来计算hasCode值
重写equals原则
- 当类有“逻辑相等”概念,当改写equals时候,总要改写hashCode()
- “相等的对象必须具有相等的散列码”
- 复写equals方法时一般需复写hashCode方法。两个互相参与计算
2.LinkedHashSet
LinkedHashSet
- 是HashSet子类
- 根据元素的hashCode值决定元素的位置,使它同时使用双向链表维护元素的次序,使得元素看起来是以插入顺序保存的。
- LinkedHashSet插入性能低于HashSet,但在迭代访问Set元素时性能好
- 不允许集合元素重复
特点
-
哈希表和链表实现的Set接口,具有可预测的迭代次序
-
由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
-
由哈希表保证元素唯一,也就是说没有重复的元素
3.TreeSet
-
TreeSet是SortedSet接口的实现类,TreeSet可以保证元素处于排序状态
-
TreeSet底层使用红黑树结构存储数据
新增方法
Comparator、first、last、lower、higher、subSet、headSet、tailSet
-
TreeSet有两种排序:自然排序和定制排序。默认自然排序
-
TreeSet、TreeMap采用红黑树存储结构
特点
有序、查询速度比list快
自然排序
1.TreeSet会调用集合元素的compareTo(obj)来比较元素大小,然后按集合元素升序排列
2.添加进TreeSet的元素必须实现Comparable接口
3.相同类的实例才会比较大小,所以添加元素应为同一类
4.重写元素对象的equals方法时应注意应与compareTo返回结果一致
定制排序
1.如果元素所属类没有实现Comparable接口,不希望按照升序或某种属性比较
2.将实现Comparator的实例传给TreeSet构造器
三、Map接口
Map接口
- 用于保存具有映射关系的数据:key-value
- key、value可以是任何类型数据
- Map的key用Set来存放,不允许重复,即同一个Map对象所对应的类,需重写hashCode和equals方法
- 常用String作为map的key
- key-value一对一关系
- Map接口的实现类HashMap、TreeMap、LinkedHashMap和Properties。常用HashMap
方法
- put(key,value)、putAll(map)添加
- remove(key)删除、clear:清空map数据
- get(key)
- containsKey(key):是否包含key、containsValue(value)是否包含value
- size键值对个数
- isEmpty、equals
- keySet:返回key构成的set集合
- values:返回value构成的Collection集合
- entrySet:返回key-value构成的Set集合
map遍历方法
方法一、
- 获取所有键的集合,用keySet()实现
- 遍历键的集合,获取到每一个键,用增强for
- 根据键去找值,用get实现
方法二、
-
获取所有键值对对象集合
Set<Map.Entry<K,V>> entry()实现
-
遍历键值对对象集合,得到每一个键值对对象
增强for
-
根据键值对对象获取键和值
getKey得到键,getValue()得到值
1.HashMap
- key构成集合是Set:无序、不可重复,所以可以所在类要重写equals、hashCode
- value构成集合是Collection:无序的、可重复,所以value所在类重写equals
- 判断key相等标准:equals返回true,hashCode值相同
- 判断value相等的标准:equals返回true
HashMap的存储结构
- JDK 7及以前版本:HashMap是数组+链表结构(即链地址法)
- JDK 8发布后:HashMap是数组+链表+红黑树实现
JDK7
JDK8
2.LinkedHashMap
- 在HashMap存储结构基础上,使用了一对双向链表来记录添加元素的顺序
- 与LinkedHashSet类似,可以维护Map迭代顺序,与键值对插入顺序一致
3.TreeMap
- TreeMap需要根据key-value对进行排序。保证所有键值对处于有序状态
- 底层使用红黑树结构存储数据
- TreeMap的key的排序:
- 自然排序:所有key必须实现Comparable接口,所有key应为同一类对象,否则抛出ClassCastException
- 定制排序:创建TreeMap时,传入一个Comparator对象,该对象负责对TreeMap的key排序,此时不需要key实现Comparable接口
- 判断两个key相等:两个key通过compareTo或compare返回0
4.HashTable
- HashTable是古老的Map实现类,Hashtable不同于HashMap:Hashtable是线程安全的
- 实现原理和HashMap相同,功能相同,底层都是用哈希表结构,查询快
- 不同的是:Hashtable不允许使用null作为key或value
- 也不能保证key-value对顺序
- 判断相等与HashMap一样
5.Properties
- Properties是Hashtable的子类。该对象用于处理属性文件
- key和value都为字符串类型
- 存取数据,使用:setProperty(key,value)和getProperty(key)方法
Properties pros = new Properties();
pros.load(new FileInputStream("jdbc.properties"));
String user = pros.getProperty("user");
四、Collections工具类
Collections是一个操作Set、List、Map等集合的工具类
排序操作(均为static方法)
- reverse(List):反转List中元素的顺序
- shuffle(List):对List集合元素进行随机排序
- sort(List):根据自然顺序进行升序排序
- sort(List,Comparator):根据指定Comparator排序
- swap(List,int,int):交换
常用方法
max、min、copy(List dest,src):src内容复制到dest中、replace(list,old,new):新值替换、frequency(Collection,Object):出现次数
同步控制
- Collections提供多个synchronizedXxx()方法,可以将指定集合包装成线程同步的集合。从而解决多线程并发访问集合时线程的安全问题。
Enumeration:是Iterator迭代器的古老版本
知识图谱
在线查看:java集合
多谢支持!留下宝赞!获取知识图请私信!