Java高级特性之集合
Java高级特性之集合
Java集合框架
一、Java集合框架概述
1、数组与集合的区别:
1)数组长度不可变化而且无法保存具有映射关系的数据;集合类用于保存数量不确定的数据,以及保存具有映射关系的数据。
2)数组元素既可以是基本类型的值,也可以是对象;集合只能保存对象。
2、Java集合类主要由两个根接口Collection和Map派生出来的,Collection派生出了三个子接口:List、Set、Queue(Java5新增的队列),因此Java集合大致也可分成List(有序、可重复集合、可直接根据元素的索引来访问)、Set(无序、不可重复集合、只能根据元素本身来访问)、Queue(队列集合)、Map(存储key-value对的集合,可根据元素的key来访问value)这四种。
二、Java集合常见接口及实现类
1、Collection接口常见方法
2、List集合
实现List接口的集合主要有:ArrayList、LinkedList、Vector、Stack。
它们都可以容纳所有类型的对象,包括 null,允许重复,并且都保证元素的存储顺序。(可重复,有顺序)
1)ArrayList
ArrayList 对数组进行了封装,实现了长度可变的数组(动态数组),和数组采用相同存储方式,在内存中分配连续的空间,它的优点在于遍历元素和随即访问元素的效率比较高。
ArrayList特点:线程不安全,查询速度快;底层数据结构是数组结构;扩容增量:原容量的 1.5倍, 如 ArrayList的容量为10,一次扩容后是容量为15。
2)LinkedList
LinkedList是List接口的另一个实现,除了可以根据索引访问集合元素外,LinkedList还实现了Deque接口,可以当作双端队列来使用,也就是说,既可以当作“栈”使用,又可以当作队列使用。
LinkedList 采用链表存储方式,优点在于插入、删除元素时效率比较高,它提供了额外的 addFirst()、addLast()、removeFirst()和 removeLast()等方法,可以在LinkedList 的首部或尾部进行插入或者删除操作。
3)Vector
与ArrayList相似,但是Vector是同步的。所以说Vector是线程安全的动态数组。它的操作与ArrayList几乎一样。
3、Set集合
实现Set集合的接口主要有:HashSet、TreeSet、LinkedHashSet;
Set集合与Collection的方法相同,由于Set集合不允许存储相同的元素,所以如果把两个相同元素添加到同一个Set集合,则添加操作失败,新元素不会被加入,add()方法返回false。(无序、不重复)
1)HashSet
HashSet是按照hash算法来存储元素的,因此具有很好的存取和查找性能。
HashSet存储原理如下:
当向HashSet集合存储一个元素时,HashSet会调用该对象的hashCode()方法得到其hashCode值,然后根据hashCode值决定该对象的存储位置。HashSet集合判断两个元素相等的标准是(1)两个对象通过equals()方法比较返回true;(2)两个对象的hashCode()方法返回值相等。因此,如果(1)和(2)有一个不满足条件,则认为这两个对象不相等,可以添加成功。如果两个对象的hashCode()方法返回值相等,但是两个对象通过equals()方法比较返回false,HashSet会以链式结构将两个对象保存在同一位置,这将导致性能下降,因此在编码时应避免出现这种情况。
HashSet查找原理如下:
基于HashSet以上的存储原理,在查找元素时,HashSet先计算元素的HashCode值(也就是调用对象的hashCode方法的返回值),然后直接到hashCode值对应的位置去取出元素即可,这就是HashSet速度很快的原因。
HashSet特点:
不能保证元素的顺序;集合元素值可以是null;线程不安全,存取速度快;底层实现是一个HashMap(保存数据),实现Set接口;默认初始容量为16;加载因子为0.75:即当 元素个数 超过 容量长度的0.75倍 时,进行扩容;扩容增量:原容量的 1 倍;如 HashSet的容量为16,一次扩容后是容量为32。
2)LinkedHashSet
LinkedHashSet是HashSet的一个子类,具有HashSet的特性,也是根据元素的hashCode值来决定元素的存储位置。但它使用链表维护元素的次序,元素的顺序与添加顺序一致。由于LinkedHashSet需要维护元素的插入顺序,因此性能略低于HashSet,但在迭代访问Set里的全部元素时由很好的性能。
3)TreeSet
TreeSet可以保证元素处于排序状态,它采用红黑树的数据结构来存储集合元素。TreeSet支持两种排序方法:自然排序和定制排序,默认采用自然排序。
♦ 自然排序
TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素的大小关系,然后将元素按照升序排列,这就是自然排序。如果试图将一个对象添加到TreeSet集合中,则该对象必须实现Comparable接口,否则会抛出异常。当一个对象调用方法与另一个对象比较时,例如obj1.compareTo(obj2),如果该方法返回0,则两个对象相等;如果返回一个正数,则obj1大于obj2;如果返回一个负数,则obj1小于obj2。
♦ 定制排序
想要实现定制排序,需要在创建TreeSet集合对象时,提供一个Comparator对象与该TreeSet集合关联,由Comparator对象负责集合元素的排序逻辑。
综上:自然排序实现的是Comparable接口,定制排序实现的是Comparator接口。
4、Map集合
Map接口采用键值对Map的存储方式,保存具有映射关系的数据,因此,Map集合里保存两组值,一组值用于保存Map里的key,另外一组值用于保存Map里的value,key和value可以是任意引用类型的数据。key值不允许重复,可以为null。如果添加key-value对时Map中已经有重复的key,则新添加的value会覆盖该key原来对应的value。
常用实现类主要有HashMap、LinkedHashMap、TreeMap。
1)HashMap
对于HashMap而言,key是唯一的,不可以重复的。所以,以相同的key 把不同的value插入到 Map中会导致旧元素被覆盖,只留下最后插入的元素。不过,同一个对象可以作为值插入到map中,只要对应的key不一样 。
HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的。
HashMap工作原理如下:
HashMap基于hashing原理,通过put()和get()方法存储和获取对象。当我们将键值对传递给put()方法时,它调用建对象的hashCode()方法来计算hashCode值,然后找到bucket位置来储存值对象。当获取对象时,通过建对象的equals()方法找到正确的键值对,然后返回对象。HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会存储在链表的下一个节点中。
HashMap特点:
Map提供了一种映射关系,元素是以键值对(key-value)的形式存储的,能根据key快速查找value;
Map中的键值对以Entry类型的对象实例形式存在;
key值不能重复,value值可以重复;
key对value是多(一)对一的关系;
Map接口提供了返回key值集合、value值集合、Entry值集合,的方法;
Map支持泛型,形式如:Map;
默认初始容量为16;
加载因子为0.75:即当 元素个数 超过 容量长度的0.75倍 时,进行扩容;
扩容增量:原容量的 1 倍。
2)LinkedHashMap
LinkedHashMap使用双向链表来维护key-value对的次序(其实只需要考虑key的次序即可),该链表负责维护Map的迭代顺序,与插入顺序一致,因此性能比HashMap低,但在迭代访问Map里的全部元素时有较好的性能。
大多数情况下,只要不涉及线程安全问题,Map基本都可以使用HashMap,不过HashMap有一个问题,是迭代HashMap的顺序并不是HashMap放置的顺序,也就是无序。HashMap的这一缺点往往会带来困扰,因为有些场景,我们期待一个有序的Map。这个时候,LinkedHashMap就闪亮登场了,它虽然增加了时间和空间上的开销,但是通过维护一个运行于所有条目的双向链表,LinkedHashMap保证了元素迭代的顺序。该迭代顺序可以是插入顺序或者是访问顺序。
LinkedHashMap可以认为是HashMap+LinkedList,即它既使用HashMap操作数据结构,又使用LinkedList维护插入元素的先后顺序。
LinkedHashMap的基本实现思想就是----多态。
3)TreeMap
TreeMap是SortedMap的实现类,是一个红黑树的数据结构,每个key-value对作为红黑树的一个节点。TreeMap存储key-value对时,需要根据key对节点进行排序。TreeMap也有两种排序方式:
♦ 自然排序:TreeMap的所有key必须实现Comparable接口,而且所有的key应该是同一个类的对象,否则会抛出ClassCastException。
♦ 定制排序:创建TreeMap时,传入一个Comparator对象,该对象负责对TreeMap中的所有key进行排序。
TreeMap特点:
·TreeMap是非线程安全的;
·TreeMap是用键来进行升序顺序来排序的。通过Comparable 或 Comparator来排序;
·和HashMap一样,如果插入重复的元素,后面的元素会覆盖前面的;
·键不可以为null(如果比较器对null做了处理,就可以为null),但是值可以为null。
5、遍历
第一种:for循环遍历
1 for (int i = 0; i < heros.size(); i++) {
2 Hero h = heros.get(i);
3 System.out.println(h);
4 }
第二种:迭代器遍历
1 System.out.println("--------使用while的iterator-------");
2 Iterator it= heros.iterator();
3 //从最开始的位置判断"下一个"位置是否有数据
4 //如果有就通过next取出来,并且把指针向下移动
5 //直到"下一个"位置没有数据
6 while(it.hasNext()){
7 Hero h = it.next();
8 System.out.println(h);
9 }
10 //迭代器的for写法
11 System.out.println("--------使用for的iterator-------");
12 for (Iterator iterator = heros.iterator(); iterator.hasNext();) {
13 Hero hero = (Hero) iterator.next();
14 System.out.println(hero);
15 }
第三种:增强for循环
1 System.out.println("--------增强型for循环-------");
2 for (Hero h : heros) {
3 System.out.println(h);
4 }
原文地址https://www.cnblogs.com/jacob-wuhan/p/12974025.html
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
如何理解Java中的自动拆箱和自动装箱?
如何理解Java中的自动拆箱和自动装箱? 小伟刚毕业时面的第一家公司就被面试官给问住了... 如何理解Java中的自动拆箱和自动装箱? 自动拆箱?自动装箱?什么鬼,听都没听过啊,这...这..知识盲区... 回到家后小伟赶紧查资料,我透,这不就是问基本类型跟封装类型吗,面试官整啥名词呢... 别问结果,问就是没过。 1、什么是自动装箱,自动拆箱定义:基本数据类型和包装类之间可以自动地相互转换 理解:装箱就是自动将基本数据类型转换为封装类型,拆箱就是自动将封装类型转换为基本数据类型。 我们知道,Java中提供了四大类基本数据类型,分别是:整数、浮点数、字符型和布尔型,其中: 整数包含:byte、int、short、long浮点数包含:float、double字符类型:char布尔类型:boolean基本数据类型相信大家一定很熟悉了吧,来来来,说说他们的取值范围~ 数据类型 取值范围byte -128 ~ 127short -32786 ~ 32767int -4294967296 ~ 4294967295long -2^64^ ~ 2^64^ -1float 3.4e-038 ~ 3.4...
- 下一篇
要小心 JavaScript 的事件代理
要小心 JavaScript 的事件代理 我们知道,如果给 form 里面的 button 元素绑定事件,需要考虑它是否会触发 form 的 submit 行为。除此之外,其它场合给 button 元素绑定事件,你几乎不用担心这个事件会有什么非预期的附加效果,很自然地会这样写事件处理代码: var button = document.querySelector('button')button.addEventListener('click', function (e) { console.log('点击了按钮')})你之所以放心这么写,是因为这个 button 元素没有使用事件代理,即没有代理任何子元素的事件。 事件代理的意思是,你要为一个元素绑定事件,但你不是直接把事件绑定到这个元素自己身上,而是绑定到这个元素的父元素上。当子元素的某个事件(比如点击事件)触发时,它的父元素相同的事件也会触发(我们常说的事件冒泡),此时我们说父元素代理了子元素的事件。 举个例子,比如一个 button 元素中包含一个齿轮图标: <use xlink:href="#gear"></us...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Hadoop3单机部署,实现最简伪集群
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16