java中List、Map、Set、Collection、Stack、Queue等的使用

java中这几个东西是比较常用的,虽然我用的不多,也正是因为用的不多,所以我一直搞不清楚他们之间的具体用法以及相互之间的关系,现在特单独作为一个东西来总结一下。

 

本文参考一下资料:

1.《java编程思想》一书第11章

2.http://blog.sina.com.cn/s/blog_a345a8960101k9vx.html

3.http://f51889920.iteye.com/blog/1884810

4.http://blog.csdn.net/speedme/article/details/22398395

5.http://www.tuicool.com/articles/qeEzym

6.http://blog.csdn.net/hguisu/article/details/7644395

在《java编程思想》一书中,这几个东西放到一章里面讲的,是在第11章。分了好多的小节去讲的,看了一会,看的头疼,但是基本上好多东西都可以明白,比较容易梳理。

首先放个图在前面,展示下他们各个集合类之间的关系,如下:

java集合框架的基本接口/类层次结构

java.util.Collection [I]
+--java.util.List [I]+--java.util.ArrayList [C]+--java.util.LinkedList [C]+--java.util.Vector [C]+--java.util.Stack [C]
+--java.util.Set [I]+--java.util.HashSet [C]+--java.util.SortedSet [I]+--java.util.TreeSet [C]java.util.Map [I]
+--java.util.SortedMap [I]+--java.util.TreeMap [C]
+--java.util.Hashtable [C]
+--java.util.HashMap [C]
+--java.util.LinkedHashMap [C]
+--java.util.WeakHashMap [C][I]:接口
[C]:类

那么,为什么要有集合类?

面向对象的语言对事物的体现都是以对象的形式,为了方便对多个对象操作,就要对对象进行存储,集合类就是对多个对象进行存储的一种方式。

数组和集合类有何不同?

最主要的区别是长度可变不可变问题。数组可以存储对象,但是长度是固定的,不可变的。集合长度是可变的。其次,数组中可以存储基本数据类型,集合只能存储对象。集合的一个比较大的优点是可以存储不同类型的对象。数组不可以。

下面就开始各种总结。

Collection接口

Collection接口是最基本的集合接口,代表一组Object集合,这些Object被称作Collection的元素,所有实现Collection接口的类型必须提供两个标准的构造函数:无参数的构造函数用于创建一个空的Collection,有一个Collection参数的构造函数用于创建一个新的Collection,这个新的Collection与传入的Collection有相同的元素后一个构造函数允许用户复制一个Collection。这些都比较容易理解。

1 Collection<Integer> ci = new ArrayList<Integer>();
2 Collection<Integer> ci2 = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5));

并且注意Collection中没有get()方法,要想查看或者操作Collection中的元素只能遍历,使用的是iterator()方法,使用该方法可以逐一访问Collection的每一个元素。

1 Iterator it = collection.iterator();//获得迭代
2 while(it.hasNext()){
3       Object obj = it.next();//得到下一个元素    
4 }

由上图可知,Collection分为Lst接口和Set接口。

List接口

  List接口是有序的Collection,使用该接口能精确控制每个元素的插入位置,可以使用索引来访问List中的元素,跟数组是很类似的。并且List中允许有重复元素,当然有些List的实现类不允许重复元素的存在。

  List中有iterator()方法,还有listIterator方法,返回一个ListIterator接口,这个接口比标准的Iterator接口相比,多了一些add之类的方法,允许添加、删除、设置元素值以及向前或者向后遍历等。

  如上图,List下有几个常用类:LinkedList、ArrayList和Vector以及Stack。

  (1)ArrayList类:实现了可变大小的数组。它允许包含所有元素,包括null。每个ArrayList实例都有一个容量,即用于存储元素的数组的大小,这个容量可以随着不断添加新元素而自动增加,但增长算法没有定义,当插入大量元素时,插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。

    (2)LinkedList类:允许null元素,提供额外的get,remove和insert方法,这使得LinkedList可以用作stack、queue或双向队列。它可以再List的中间插入和移除,在这方面比ArrayList有效,但是在随机访问方面就没有ArrayList有效了。如果多个线程同时访问一个List,则必须自己实现访问同步,一种解决方法是在创建List时构造一个同步的List:

List list = Collection.synchronizedList(new LinkedList(……));

  (3)Vector类:Vector跟ArrayList非常类似,但是Vector是同步的,由Vector创建的Iterator,虽然和ArrayList创建的 Iterator是同一接口,但是,因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了Vector的状态(例如,添加或删除了一些元素),这时调用Iterator的方法时将抛出ConcurrentModificationException,因此必须捕获该异常。

  (4)Stack类:继承自Vector,实现一个后进先出的栈。提供了几个基本方法,push、pop、peak、empty、search等。

总结:

  • List:元素是有序的,元素可以重复。因为该集合体系有索引。
    • ArrayList:底层的数据结构使用的是数据结构。
      • 查询速度很快。
      • 增删稍慢。
      • 线程不同步。
      • 默认长度为10增长率为50%。
    • LinkedList:底层使用的链表数据结构。
      • 增删速度很快。
      • 查询稍慢。
    • Vector:底层是数组数据结构。1.0出现
      • 线程同步
      • 被ArrayList替代了。
      • 长度增长率100%。

Set接口

Set接口是继承自Collection的,它不能包含有重复元素。Set中最多有一个null元素。

因为Set的这个制约,在使用Set集合的时候,应该注意:
1,为Set集合里的元素的实现类实现一个有效的equals(Object)方法。
2,对Set的构造函数,传入的Collection参数不能包含重复的元素。
Set下有几个set类,HashSet、SortedSet、TreeSet,用的较多的是HashSet,其他两种基本不常用,以后慢慢补充该方面知识,下面说HashSet。
(1)HashSet,底层数据结构式哈希表,由哈希表支持,不保证集合的迭代顺序,特别是不保证该顺序恒久不变,此类允许使用null元素。HashSet保证元素唯一性的方法是通过元素的两个方法,hashCode和equals来完成。如果元素的HashCode值相同,才会判断equals是否为true。如果元素的hashCode值不同,不会调用equals。
(2)TreeSet:底层数据结构式二叉树。注:添加元素必须实现Comparable接口或在实例TreeSet时指定比较器。可以对Set集合中的元素进行排序。保证元素唯一性的依据:compareTo方法return 0;
Map接口
Map集成Collection接口,Map和Collection是两种不同的集合,Collection是值(value)的集合,Map是键值对(key,value)的集合。包含几种主要类和接口:HashMap、LinkedMap、WeakHashMap、SortedMap、TreeMap、HashTable等几种。
(1)Hashtable继承Map接口,实现一个key-value映射的哈希表。任何非空(non-null)的对象都可作为key或者value。添加数据使用put(key, value),取出数据使用get(key),这两个基本操作的时间开销为常数。
  (2)WeakHashMap类,WeakHashMap是一种改进的HashMap,它对key实行“弱引用”,如果一个key不再被外部所引用,那么该key可以被GC回收。
总结:
如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。
如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。
在除需要排序时使用TreeSet,TreeMap外,都应使用HashSet,HashMap,因为他们 的效率更高。
要特别注意对哈希表的操作,作为key的对象要正确复写equals和hashCode方法。
容器类仅能持有对象引用(指向对象的指针),而不是将对象信息copy一份至数列某位置。一旦将对象置入容器内,便损失了该对象的型别信息。
尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。
注意:
1、Collection没有get()方法来取得某个元素。只能通过iterator()遍历元素。
2、Set和Collection拥有一模一样的接口。
3、List,可以通过get()方法来一次取出一个元素。使用数字来选择一堆对象中的一个,get(0)...。(add/get)
4、一般使用ArrayList。用LinkedList构造堆栈stack、队列queue。
5、Map用 put(k,v) / get(k),还可以使用containsKey()/containsValue()来检查其中是否含有某个key/value。
HashMap会利用对象的hashCode来快速找到key。
6、Map中元素,可以将key序列、value序列单独抽取出来。
使用keySet()抽取key序列,将map中的所有keys生成一个Set。
使用values()抽取value序列,将map中的所有values生成一个Collection。
为什么一个生成Set,一个生成Collection?那是因为,key总是独一无二的,value允许重复。

转载于:https://www.cnblogs.com/Pillar/p/4226549.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/292030.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开发文档模板_需求文档模板一堆什么样的适合你呢?

产品经理的日常中用的最多的是产品需求文档&#xff0c;这个文档应该可以说是产品经理将需求落到是明面上的一步。我们的文档需要给相关的人员进行共同的看&#xff0c;不然文档就没有存在的意义了&#xff0c;文档不只是简单的线框图和一些自己也看不明白的词汇。实际中很少开…

Briefly unavailable for scheduled maintenance message after doing automatic upgrade

为什么80%的码农都做不了架构师&#xff1f;>>> 今天突然不能打开wordpress&#xff0c;报了“Briefly unavailable for scheduled maintenance message after doing automatic upgrade” 这个错误&#xff0c;一下懵逼了。 Google之后&#xff0c;发现是wordpress…

搞IT的技术人员为什么会如此苦逼

http://www.cnblogs.com/springmvc-hibernate/archive/2012/05/10/2493733.html —————————————————————————————————————————————————————— 为什么苦逼&#xff1f; 原因一大堆&#xff0c;对于外部的因数&#xff0c;我…

为什么越来越多的开发者选择使用Spring Boot

Web应用开发背景 使用Java做Web应用开发已经有近20年的历史了&#xff0c;从最初的Servlet1.0一步步演化到现在如此多的框架&#xff0c;库以及整个生态系统。经过这么长时间的发展&#xff0c;Java作为一个成熟的语言&#xff0c;也演化出了非常成熟的生态系统&#xff0c;这…

【Blog.Core开源】快速预览Admin界面效果

( 半盏屠苏犹未举&#xff0c;灯前小草写桃符 )书接上文《【Blog.Core开源】开发插件&#xff0c;给Swagger加权》&#xff0c;在上篇文章中&#xff0c;我们给项目的接口文档增加了一个控制界面&#xff0c;可以输入用户名密码&#xff0c;这样也算是简单的一个加密控制了&…

视图添加字段_Odoo开发教程2-为模型添加字段

开启开发者模式后&#xff0c;我们可通过菜单 Settings > Technical > Database Structure > Models来查看模型的定义。这时搜索 res.partner(未安装其它应用的情况下第一个即是)&#xff0c;对应的模型描述为 Contact。点击打开表单视图&#xff0c;这时就可以看到 p…

linux之通过htop操作进程使用总结

1、htop介绍 top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器,htop比top更加人性化,有具体界面可以操作,读者可以先使用top看下效果,然后再安装htop. 2、安装htop 输入下面命令 sudo apt-get install htop 3、效…

6大奖项!首届 .NET 黑客松大赛圆满收官!

.NET Conf China 2021 是面向开发人员的社区峰会&#xff0c;基于 .NET Conf 2021&#xff0c;庆祝 .NET 6 的发布和回顾过去一年来 .NET 在中国的发展。峰会由来自北京、上海、苏州、深圳、武汉、广州、青岛、烟台、杭州等各地区的 .NET 技术社区共同发起举办&#xff0c;由微…

看完这套书才发现,以前的四大名著都白看了!

▲ 点击查看四大名著是我国最经典的古典文学作品&#xff0c;代表着传统文化在小说创作方面的最高成就。同时&#xff0c;也是必学书、必读书、必考书。从小了说&#xff0c;在语文学习上&#xff0c;全国统一的语文教材里&#xff0c;五年级下册已出现了四大名著的章节。作为整…

在Windows Live Writer中插入C# code

平时都是用Windows Live Writer写博客&#xff0c;发布博客。遇到需要插入代码都是先在notepad中写好&#xff0c;或者是拷贝到notepad&#xff0c;再从notepad中拷到Windows Live Writer&#xff0c;比较麻烦。在博客中使用插件Code Snippet就能很好解决这个问题。 下载地址&a…

linux之vifm和ranger操作文件管理器使用总结

1、介绍vifm和ranger vifm和ranger都是有图形的文件管理操作,有点类是windows上面的“我的电脑” 2、安装vifm和ranger 在终端输入下面命令 sudo apt-get install vifmsudo apt-ger install ranger 3、常规使用vifm 安装成功之后,我们在控制台输入vifm命令,然后显示下面…

.NET 运行时设置

.NET 运行时设置.NET 5&#xff08;包括 .NET Core 版本&#xff09;支持使用配置文件和环境变量在运行时配置 .NET 应用程序的行为。如果出现以下情况&#xff0c;则运行时配置是一个不错的选择&#xff1a;你不拥有或控制应用程序的源代码&#xff0c;因此无法以编程方式对其…

ElasticSearch——学习笔记

2019独角兽企业重金招聘Python工程师标准>>> Relational DB -> Databases -> Tables -> Rows -> Columns Elasticsearch -> Indices -> Types -> Documents -> Fields 转载于:https://my.oschina.net/u/2307114/blog/799905

linux之用wget下sublime简单使用总结

1、简单介绍wget 1&#xff09;、wget命令在linux系统上面主要通过url下载&#xff0c; wget url 2&#xff09;、比如我们需要断点续传我们加上参数 -c wget -c url 2、下载sublime 1&#xff09;电脑32位 wget http://c758482.r82.cf2.rackcdn.com/Sublime\ Text\ 2.0.2.tar.…

C# dynamic 类型用法举例

dynamic类型允许编写忽略编译期间的类型检查的代码。编译器假定&#xff0c;给dynamic类型的对象定义的任操作都是有效的。如果该操作无效&#xff0c;则在代码运行之前不会检测该错误&#xff0c;如下面的示例所示:这个示例没有编译&#xff0c;因为它调用了staticPerson.GetF…

在微信小程序中绘制图表(part2)

本期大纲 1、确定纵坐标的范围并绘制 2、根据真实数据绘制折线 相关阅读&#xff1a;在微信小程序中绘制图表&#xff08;part1&#xff09;在微信小程序中绘制图表&#xff08;part3&#xff09; 关注我的 github 项目 查看完整代码。 确定纵坐标的范围并绘制 为了避免纵坐标的…

Windows 8.1 新增控件之 CommandBar

上一篇为大家介绍了AppBar 的相关内容&#xff0c;本篇继续介绍CommandBar 的使用方法。与AppBar 相比而言&#xff0c;CommandBar 在开发使用方面较为单一&#xff0c;在按键布局上分为主控区&#xff08;Primary Commands&#xff09;与辅控区&#xff08;Secondary Commands…