1.List、Set、Map概述

Collection List Set Map 这些都代表了Java中的集合,这里主要从其元素是否有序,是否可重复,是否线程安全来进行区别记忆,以便恰当地使用。List接口对Collection进行了简单的扩充,它的具体实现类常用的有ArrayList、LinkedList和Vector。ArrayList是一种类似数组的形式进行存储,因此它的随机访问速度极快;LinkedList的内部实现是链表,它适合于在链表中间需要频繁进行插入和删除操作;Vector是线程安全的ArrayList;一般的Iterator只能对容器进行向前遍历,而listIterator()则继承了Iterator的思想,并提供了对List进行双向遍历的方法(hasPrevious()和previous())。 
      Set接口也是Collection的一种扩展,而与List不同的时,在Set中的对象元素不能重复,也就是说你不能把同样的东西两次放入同一个Set容器中。它的常用具体实现有HashSet、TreeSet、LinkedHashSet类。HashSet能快速定位一个元素,但是你放到HashSet中的对象需要实现hashCode()方法,它使用了前面说过的哈希码的算法。而TreeSet则将放入其中的元素按序存放,这就要求你放入其中的对象是可排序的,这就用到了集合框架提供的另外两个实用类Comparable和Comparator。一个类是可排序的,它就应该实现Comparable接口。有时多个类具有相同的排序算法,那就不需要在每分别重复定义相同的排序算法,只要实现Comparator接口即可。集合框架中还有两个很实用的公用类:Collections和Arrays。Collections提供了对一个Collection容器进行诸如排序、复制、查找和填充等一些非常有用的方法,Arrays则是对一个数组进行类似的操作。 
      Map是一种把键对象和值对象进行关联的容器,而一个值对象又可以是一个Map,依次类推,这样就可形成一个多级映射。对于键对象来说,像Set一样,一个Map容器中的键对象不允许重复,这是为了保持查找结果的一致性;如果有两个键对象一样,那你想得到那个键对象所对应的值对象时就有问题了,可能你得到的并不是你想的那个值对象,结果会造成混乱,所以键的唯一性很重要,也是符合集合的性质的。当然在使用过程中,某个键所对应的值对象可能会发生变化,这时会按照最后一次修改的值对象与键对应。对于值对象则没有唯一性的要求。你可以将任意多个键都映射到一个值对象上,这不会发生任何问题(不过对你的使用却可能会造成不便,你不知道你得到的到底是那一个键所对应的值对象)。Map有比较常用的实现有:HashMap、HashTable、TreeMap。HashMap也用到了哈希码的算法,以便快速查找一个键;HashTable则是线程安全的HashMap;TreeMap则是对键按序存放,因此它便有一些扩展的方法,比如firstKey(),lastKey()等,你还可以从TreeMap中指定一个范围以取得其子Map。键和值的关联很简单,用pub(Object key,Object value)方法即可将一个键与一个值对象相关联。用get(Object key)可得到与此key对象所对应的值对象。

2.List、set、map的区别与联系

1.在使用Java的时候,我们都会遇到使用集合(Collection、Map)的时候,但是Java API提供了多种集合的实现,总的说来,Java API中所用的集合类,都是实现了Collection、Map接口,其类结构如下:
     Collection<--List<--Vector                                      有序(顺序存储)                                线程安全
    Collection<--List<--ArrayList                                   有序(顺序存储)                                线程不安全
    Collection<--List<--LinkedList                                 有序(顺序存储)                                线程不安全
    Collection<--Set<--HashSet                                    无序排异                                        线程不安全
    Collection<--Set<--HashSet<--LinkedHashSet          有序排异                                         线程不安全
    Collection<--Set<--AbstractSet<--TreeSet               有序(二叉树排序)                              线程不安全
    Map<--HashMap                                                     无序                                               线程不安全
    Map<--HashMap<--LinkedHashMap                        有序(链表)                                       线程不安全
    Map<--HashTable                                                  无序                                               线程安全
    Map<--SortedMap<--TreeMap                                有序(二叉树排序)                              线程不安全

      2.基于Array的List,其实就是封装了Array所不具备的一些功能方便我们使用,它不可能走入Array的限制。性能也就不可能超越Array。所以,在可能的情况下,我们要多运用Array。另外很重要的一点就ArrayList同Vector一样是一个基于Array上的链表,但是不同的是ArrayList不是同步的。所以在性能上要比Vector优越一些,但是当运行到多线程环境中时,可需要自己管理线程的同步问题。LinkedList不同于前面两种List,它不是基于Array的,所以不受Array性能的限制。它每一个节点(Node)都包含两方面的内容:1.节点本身的数据(data);2.下一个节点的信息(nextNode)。所以当对LinkedList做添加,删除动作的时候就不用像基于Array的List一样,必须进行大量的数据移动。只要更改nextNode的相关信息就可以实现了。这就是LinkedList的优势,故LinkedList可以用来当做栈、队列和双向队列来使用。所有的List中只能容纳单个不同类型的对象组成的表,而不是Key-Value键值对,例如:[ tom,1,c ];所有的List中可以有相同的元素,例如Vector中可以有 [ tom,koo,too,koo ];所有的List中可以有null元素,例如[ tom,null,1 ];基于Array的List(Vector,ArrayList)适合查询,而LinkedList(链表)适合添加,删除操作。

3.虽然Set同List都实现了Collection接口,但是他们的实现方式却大不一样。List基本上都是以Array为基础。但是Set则是在HashMap的基础上来实现的,这个就是Set和List的根本区别。HashSet的存储方式是把HashMap中的Key作为Set的对应存储项。看看HashSet的add(Object obj)方法的实现就可以一目了然了。这个也是为什么在Set中不能像在List中一样有重复的项的根本原因,因为HashMap的key是不能有重复的;

public boolean add(Object obj){return map.put(obj, PRESENT) == null;
}

注意:LinkedHashSet:HashSet的一个子类,一个双向链表。TreeSet:SortedSet的子类,它不同于HashSet的根本就是TreeSet是有序的。它是通过SortedMap来实现的。Set实现的基础是Map(HashMap);Set中的元素是不能重复的,如果使用add(Object obj)方法添加已经存在的对象,则会覆盖前面的对象。
      4.Iterator和ListIterator主要区别在以下方面:ListIterator有add()方法,可以向List中添加对象,而Iterator不能;ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以;ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能;都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iierator仅能遍历,不能修改。 因为ListIterator的这些功能,可以实现对LinkedList等List数据结构的操作。

3.总结

1.Java所有“存储及随机访问一连串对象”的做法,array是最有效率的一种。但容量固定且无法动态改变且无法判断其中实际存有多少元素,length只是告诉我们array的容量;若撰写程序时不知道究竟需要多少对象,需要在空间不足时自动扩增容量,此时array不适用则需要使用容器类库。
      2.在各种Lists中,最好的做法是以ArrayList作为缺省选择。当插入删除频繁时,使用LinkedList();Vector总是比ArrayList慢,所以要尽量避免使用。在各种Sets中,HashSet通常优于HashTree(插入、查找)。只有当需要产生一个经过排序的序列,才用TreeSet。HashTree存在的唯一理由:能够维护其内元素的排序状态。 在各种Maps中HashMap用于快速查找。当元素个数固定,用Array,因为Array效率是最高的。即最常用的是ArrayList,HashSet,HashMap,Array。
      3、Collection没有get()方法来取得某个元素只能通过iterator()遍历元素;Set和Collection拥有一模一样的接口;一般的Iterator只能对容器进行向前遍历,而listIterator()则继承了Iterator的思想,并提供了对List进行双向遍历的方法;一般使用ArrayList。用LinkedList构造堆栈stack、队列queue。

4、Map用 put(k,v) / get(k),还可以使用containsKey()/containsValue()来检查其中是否含有某个key/value;HashMap会利用对象的hashCode来快速找到key;Map中元素,可以将key序列、value序列单独抽取出来。使用keySet()抽取key序列,将map中的所有keys生成一个Set。使用values()抽取value序列,将map中的所有values生成一个Collection。为什么一个生成Set,一个生成Collection?那是因为,key总是独一无二的,value允许重复。
       5、Map常用的四种遍历方式。如下代码:

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class Test {
public static void main(String[] args) {Map<String, Object> map = new HashMap<>();map.put("name", "luna");map.put("age", 20);/*** 1.根据map的entrySet()遍历map容器*/Set<Entry<String, Object>> set = map.entrySet();for (Entry<String, Object> entry : set) {System.out.println("map容器的key为:" + entry.getKey() + "对应的value值为—" + entry.getValue());}// 2.迭代器遍历Map容器Iterator<Entry<String, Object>> iterator = map.entrySet().iterator();while (iterator.hasNext()) {Entry<String, Object> entry = iterator.next();System.out.println("map容器的key为:" + entry.getKey() + "对应的value值为—" + entry.getValue());}/*** 3.根据map的keySet()遍历map容器*/Set<String> ketSet = map.keySet();for (String string : ketSet) {System.out.println("map容器的key为:" + string + "对应的value值为—" + map.get(string));}// 4.迭代器遍历Map容器Iterator<String> iterators = map.keySet().iterator();while (iterators.hasNext()) {String key = iterators.next();System.out.println("map容器的key为:" + key + "对应的value值为—" + map.get(key));}// 只能获map容器中的所有value的集合Collection<Object> collection = map.values();for (Object object : collection) {System.out.println(object);}}
}

Java容器List、Set、Map详解相关推荐

  1. java中list和map详解

    java中list和map详解 一.概叙 List , Set, Map都是接口,前两个继承至Collection接口,Map为独立接口, List下有ArrayList,Vector,LinkedL ...

  2. java中set和ge什么么意思,java的Collection和Map详解

    java的Collection和Map详解 线性表,链表,哈希表是常用的数据结构,在进行Java开发时,JDK已经为我们提供了一系列相应的类来实现基本的数据结构.这些类均在java.util包中.本文 ...

  3. [转] java的 Collection 和 Map 详解

    原文转自: http://www.diybl.com/course/3_program/java/javajs/2007917/71621.html 前言        线性表,链表,哈希表是常用的数 ...

  4. java map详解

    java map详解 Map 是一种键-值对(key-value)集合,Map 集合中的每一个元素都包含一个键对象和一个值对象.其中,键对象不允许重复,而值对象可以重复,并且值对象还可以是 Map 类 ...

  5. java none怎么用tomcat_在docker中部署tomcat并且部署java应用程序的步骤详解

    先给大家简单说下Docker的概念 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是 ...

  6. Java开发常见面试题详解(LockSupport,AQS,Spring循环依赖,Redis)_3

    Java开发常见面试题详解(LockSupport,AQS,Spring循环依赖,Redis)_3 总览 问题 详解 String.intern()的作用 link LeetCode的Two Sum题 ...

  7. Java并发编程最佳实例详解系列

    Java并发编程最佳实例详解系列: Java并发编程(一)线程定义.状态和属性 Java并发编程(一)线程定义.状态和属性 线程是指程序在执行过程中,能够执行程序代码的一个执行单元.在java语言中, ...

  8. java中Freemarker list指令详解

    java Freemarker中list指令主要是进行迭代服务器端传递过来的List集合. 定义 <#list nameList as names> ${names} </#list ...

  9. 【Java基础】HashMap原理详解

    [Java基础]HashMap原理详解 HashMap的实现 1. 数组 2.线性链表 3.红黑树 3.1概述 3.2性质 4.HashMap扩容死锁 5. BATJ一线大厂技术栈 HashMap的实 ...

  10. java 委托机制_通过反射实现Java下的委托机制代码详解

    简述 一直对Java没有现成的委托机制耿耿于怀,所幸最近有点时间,用反射写了一个简单的委托模块,以供参考. 模块API public Class Delegater()//空参构造,该类管理委托实例并 ...

最新文章

  1. SpringBoot整合Spring Security
  2. js折线图设置y轴刻度_手绘风格的 JS 图表库:Chart.xkcd
  3. 用特征迭代次数区分minst数据集的0和1
  4. DL:深度学习算法(神经网络模型集合)概览之《THE NEURAL NETWORK ZOO》的中文解释和感悟(二)
  5. mysql的查询语句怎么优化_MySQL查询语句如何优化
  6. ITK:二进制图像的最小和最大曲率流
  7. [2007最后一博]Url地址重写,利用HttpHander手工编译页面并按需生成静态HTML文件...
  8. xss 全编码两次_XSS进阶
  9. bind配置文件解析
  10. PCBA加工为什么要做首件检测?
  11. 玩转Python第三方库库tqdm
  12. iosclient发现_世界杯送流量活动项目总结
  13. 命令行导入 .dmp文件,亲测可行
  14. 浏览器的收藏夹在哪里打开
  15. 【简单】反转双向链表-Java
  16. vlan的基本指令_思科VLAN的基本配置命令
  17. 问题1:修改日志文件(redo log)的位置的方法
  18. 计算机移动存储设备是,移动存储器在计算机操作系统安装中的应用
  19. 六周第一次课(1月15日) 9.1 正则介绍_grep上 9.2 grep中 9.3 grep下
  20. Junit报错:Argument(s) are different! Wanted:

热门文章

  1. 线性与非线性规划:随机方向法
  2. 同步辐射X射线断层扫描成像在各行业的应用
  3. 如何利用蜂鸣器制作MIDI音乐
  4. 定制嵌入式主板需要考虑的功能
  5. 【全栈软件测试】一、测试环境和操作系统(3)VMware的安装及使用与虚拟机的创建与使用详细介绍
  6. 二元函数对xy同时求导_更新丨10分钟掌握高等数学上册函数极限求解问题(考研、期末复习均可以用)...
  7. 最新游戏陪玩源码V2.0升级版/商业版语音聊天系统源码
  8. 再见,搜不准的百度!你好,6个精准搜索技巧(还可以屏蔽广告哦~)
  9. 基于802.1q技术实现单线复用的一种思路
  10. 分布式架构和集群架构的区别