Java 集合类

Wesley13
• 阅读 782

为什么使用集合

数组长度是固定,如果要改变数组的长度需要创建新的数组将旧数组里面的元素拷贝过去,使用起来不方便。

java给开发者提供了一些集合类,能够存储任意长度的对象,长度可以随着元素的增加而增加,随着元素的减少而减少,使用起来方便一些。

数组和集合的区别

区别1:

数组既可以存储基本数据类型,又可以存储引用数据类型,基本数据类型存储的是值,引用数据类型存储的是地址值。

集合只能存储引用数据类型(对象),如果存储基本数据类型时,会自动装箱变成相应的包装类。

区别2:

数组长度是固定的,不能自动增长

集合的长度的是可变的,可以根据元素的增加而自动增长

集合基础体系图


java提供了一些集合类,这些集合类分别适用于不同的场景,下面是常用的一些集合基础体系图(图片引自网络)。

Java 集合类

Collection是接口,下面的List、Set、Queue也都是接口,并且继承了这个Collection。最下面的ArrayList、LinkedList、Vector、HashSet、TreeSet、PriorityQueue都是他们的实现类。

List:存放的数据是有顺序的,可以存放重复的数据。

LinkedList :基于链表实现,链表内存是散列的,增删快,查找慢;

ArrayList :基于数组实现,非线程安全,效率高,增删慢,查找快;

Vector :基于数组实现,效率低,增删慢,查找慢,线程安全;

Set:存放的数据是没有顺序的,不能存放重复的数据;

TreeSet:提供有序的Set集合,是自然排序,它继承了AbstractSet抽象类,相对读取慢;

HashSet :底层是由 Hash Map 实现,不允许集合有重复的值,使用该方式时需要重写 equals()和 hashCode()方法;

LinkedHashSet :继承于 HashSet,同时又基于 LinkedHashMap 来进行实现,底层使用的是 LinkedHashMap,按添加顺序排序;

Queue:是一个队列,里面的数据是先进先出,可以存放重复的数据。

Collections是针对集合类的一个帮助类。提供了一系列静态方法实现对各种集合的搜索、排序、线程完全化等操作。
例如:

Collections.max(Collection coll);  取coll中最大的元素。
Collections.sort(List list);  对list中元素排序

Java 集合类

Map是接口,下面的HashMap、HashTable、AbstractMap也都是接口,并且继承了这个Map。最下面的LinkedHashMap、TreeMap是他们的实现类。

HashMap:里面存放的数据是没有顺序的,键值对可以存null键和null值,key 不能重复,值可重复,线程不安全。

LinkedHashMap :继承 了HashMap ,保存了记录的插入顺序;

HashTable:里面存放的元素不保证有序,key 不能重复,值可重复,线程安全。

TreeMap:基于红黑树 (red-black tree) 数据结构实现,按 key 排序,默认的排序方式是升序。

HashMap详情分析

HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。

HashMap的底层结构是一个数组,数组中的每一项是一条链表。

HashMap的实例有两个参数影响其性能“初始容量” 和 装填因子。

HashMap实现不同步,线程不安全,HashTable线程安全。

HashMap中的key-value都是存储在Entry中的。

HashMap可以存null键和null值,不保证元素的顺序恒久不变,通过hashCode()方法和equals方法保证键的唯一性。

hashCode()方法解决哈希冲突主要有三种方法:开放定址法,链表法,再散列法。

HashMap是采用 链表法 解决哈希冲突的。

注: 链表法是将相同hash值的对象组成一个链表放在hash值对应的槽位;

Hashtable、HashMap、ConcurrentHashMap的区别

HashMap和HashTable在功能上基本相同,但HashMap是线程不安全的,HashTable是线程安全的;

HashMap的key和value都是可以为null的,当get()方法返回null值时,HashMap中可能存在某个key,只不过该key值对应的value为null,也有可能是HashMap中不存在该key,所以不能使用get()==null来判断是否存在某个key值,对HashMap和HashTable,提供了containsKey()方法来判断是否存在某个key。

HashTable是不允许key和value为null的。HashTable中的方法大部分是同步的,因此HashTable是线程安全的。

在JDK1.5以后,出现了ConcurrentHashMap和HashTable功能很像,不允许为null的key或value,但它不是通过给方法加synchronized方法进行并发控制的。在ConcurrentHashMap中使用分段锁技术Segment,将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问,能够实现真正的并发访问。效率也比HashTable好的多。

TreeMap、HashMap、LinkedHashMap的区别

LinkedHashMap保存了数据的插入顺序,底层是通过一个双链表的数据结构来维持这个插入顺序的,key和value都可以为null。

TreeMap实现了SortMap接口,它保存的记录是根据键值key排序,默认是按key升序排列。也可以指定排序的Comparator。

HashMap、LinkedHashMap和TreeMap都是线程不安全的,提供两种遍历Map的方法如下
推荐方式

Map<String, Integer> map = new HashMap<String, Integer>(20); 
//直接遍历出Entry 
for(Map.Entry<String, Integer> entry : map.entrySet()){ 
     System.out.println("key-->"+entry.getKey()+",value-->"+m.get(entry.getValue())); 
}

这种方式相当于首先通过Set<Map.Entry<String,Integer>> set =  map.entrySet();方式拿到Set集合,而Set集合是可以通过foreach的方式遍历的。

普通方式

Map<String, Integer> map = new HashMap<String, Integer>(20); Iterator<String> keySet = map.keySet().iterator(); //遍历Hash表中的key值集合,通过key获取value 
while(keySet .hasNext()){ 
      Object key = keySet .next(); 
      System.out.println("key-->"+key+",value-->"+m.get(key)); 
}

HashSet内部使用Map保存数据,即将HashSet的数据作为Map的key值保存,这也是HashSet中元素不能重复的原因。而Map中保存key值的,会去判断当前Map中是否含有该Key对象,内部是先通过key的hashCode,确定有相同的hashCode之后,再通过equals方法判断是否相同。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
java ArrayList集合
ArrayList集合是程序中最常见的一种集合,它属于引用数据类型(类)。在ArrayList内部封装了一个长度可变的数组,当存入的元素超过数组长度时,ArrayList会在内存中分配一个更大的数组来存储这些元素,因此可以将ArrayList集合看作一个长度可变的数组。集合的创建格式导包:importjava.util.ArrayList;
Chase620 Chase620
3年前
ArrayList底层
一、ArrayList集合底层数据结构1.ArrayList集合介绍List集合的可调整大小数组实现。2.数组结构介绍增删快:每次增加删除元素,都需要更改数组长度、拷贝以及移除元素位置。查询快:由于数组在内存中是一块连续空间,因此可以根据地址索引的方式快速获
Wesley13 Wesley13
3年前
Java开发者容易犯的十个错误
!(https://oscimg.oschina.net/oscnet/c9f00cc918684fbe8a865119d104090b.gif)Top1.数组转换为数组列表将数组转换为数组列表,开发者经常会这样做:\java\List<StringlistArrays.asList(arr);Arr
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
3年前
HashMap 的底层实现原理
HashMap是一个用于存储KeyValue键值对的集合,每一个键值对也叫做Entry。这些个Entry分散存储在一个数组当中,这个数组就是HashMap的主干。HashMap数组每一个元素的初始值都是Null。 !(https://oscimg.oschina.net/oscnet/8495d30fe00a2865dd74088d2
Wesley13 Wesley13
3年前
.Net转Java自学之路—基础巩固篇十三(集合)
集合:集合是用于存储对象的一个工具。  集合与数组的特点    相同点:都是一个容器    不同点:      集合:可以存储对象,只能存储对象,集合长度可变。      数组:可以存储对象,也可以存储基本数据类型,数组长度固定。  容器对象有很多种,通过内部的数据结构来区分,数据结构就是一种数据存储方式。  在不断
Wesley13 Wesley13
3年前
Java集合笔记
1.1集合概述在前面基础班我们已经学习过并使用过集合ArrayList<E,那么集合到底是什么呢?集合:集合是java中提供的一种容器,可以用来存储多个数据。集合和数组既然都是容器,它们有啥区别呢?数组的长度是固定的。集合的长度是可变的。数组中存储的是同一类型的元素,可以存储基本数据类