当前位置: 首页 > news >正文

Java 集合类 List Set Map 哪些线程安全

Java中的集合包括三大类,它们是Set、List和Map,
  • Set(集)
  • List(列表)
  • Map(映射)
它们都处于java.util包中,Set、List和Map都是接口,它们有各自的实现类。
(1)List的实现类主要有ArrayList,LinkedList,Vector
(2)Set的实现类主要有HashSet和TreeSet
(3)Map的实现类主要有HashMap和TreeMap,HashTable;
解释:

   (1)List,Set都是继承自Collection接口,Map则不是

   (2)List中的对象按照索引位置排序,可以有重复对象,允许按照对象在集合中的索引位置检索对象,如通过list.get(i)方式来获得List集合中的元素。
   (3)Set中的对象不按特定方式排序,并且没有重复对象。但它的有些实现类能对集合中的对象按特定方式排序,例如TreeSet类,它可以按照默认排序,也可以通过实现             java.util.Comparator<Type>接口来自定义排序方式。  
(4) Map中的每一个元素包含一个键对象和值对象,它们成对出现。键对象不能重复,值对象可以重复。

线程安全类

在集合框架中,有些类是线程安全的,这些都是jdk1.1中的出现的。在jdk1.2之后,就出现许许多多非线程安全的类。 下面是这些线程安全的同步的类:

vector:就比arraylist多了个同步化机制(线程安全),因为效率较低,现在已经不太建议使用。在web应用中,特别是前台页面,往往效率(页面响应速度)是优先考虑的。

statck:堆栈类,先进后出

hashtable:就比hashmap多了个线程安全

enumeration:枚举,相当于迭代器

除了这些之外,其他的都是非线程安全的类和接口。

线程安全的类其方法是同步的,每次只能一个访问。是重量级对象,效率较低。

其他:

1. hashtable跟hashmap的区别

hashtable是线程安全的,即hashtable的方法都提供了同步机制;hashmap不是线程安全的,即不提供同步机制 ;hashtable不允许插入空值,hashmap允许!

2. 多线程并发修改一 个 集合 怎么办

用老的Vector/Hashtable类 

StringBuffer是线程安全,而StringBuilder是线程不安全的。对于安全与不安全没有深入的理解情况下,易造成这样的错觉,如果对于StringBuffer的操作均是线程安全的,然而,Java给你的保证的线程安全,是说它的方法是执行是排它的,而不是对这个对象本身的多次调用情况下,还是安全的。看看下边的例子,在StringBufferTest中有一个数据成员contents它是用来扩展的,它的每一次append是线程安全的,但众多次append的组合并不是线程安全的,这个输出结果不是太可控的,但如果对于log和getContest方法加关键字synchronized,那么结果就会变得非常条理,如果换成StringBuider甚至是append到一半,它也会让位于其它在此基础上操作的线程:

最后,写一个Set 的例子: 
        Set set =new HashSet();
        String s1=new String("hello");
        String s2=s1;
        String s3=new String("world");
        
        set.add(s1);
        set.add(s2);
        set.add(s3); 
        System.out.println(set.size());

  结果是:

2

  set中不允许有重复的元素存在,因此是2,

     map的 key 集合和 set集合都不允许有重复的元素存在,list可以有重复的元素存在 

  • 1.4 区别
  • 1.4.1、Collection 和 Map 的区别

    容器内每个为之所存储的元素个数不同。
    Collection类型者,每个位置只有一个元素。
    Map类型者,持有 key-value pair,像个小型数据库。

    1.4.2、各自旗下的子类关系

    Collection
         --List:将以特定次序存储元素。所以取出来的顺序可能和放入顺序不同。
               --ArrayList / LinkedList / Vector
         --Set : 不能含有重复的元素
               --HashSet / TreeSet
          Map
         --HashMap
         --HashTable
         --TreeMap

    1.4.3、其他特征

    List,Set,Map将持有对象一律视为Object型别。

    Collection、List、Set、Map都是接口,不能实例化。
        继承自它们的 ArrayList, Vector, HashTable, HashMap是具象class,这些才可被实例化。
    vector容器确切知道它所持有的对象隶属什么型别。vector不进行边界检查。

    总结
    1. 如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。
    2. 如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。
    3. 在除需要排序时使用TreeSet,TreeMap外,都应使用HashSet,HashMap,因为他们 的效率更高。
    4. 要特别注意对哈希表的操作,作为key的对象要正确复写equals和hashCode方法。 
    5. 容器类仅能持有对象引用(指向对象的指针),而不是将对象信息copy一份至数列某位置。一旦将对象置入容器内,便损失了该对象的型别信息。
    6. 尽量返回接口而非实际的类型,如返回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允许重复。  

相关文章:

  • 安装Python的机器学习包Sklearn 出错解决方法
  • 【干货】机器学习常见算法分类汇总
  • 《Selenium自动化测试指南》目录—导读
  • 一次耐人寻味的SQL优化:除了SQL改写,还要考虑什么?
  • 《HTML5 canvas开发详解(第2版)》——2.2 基本矩形
  • 《推荐系统:技术、评估及高效算法》一1.2 推荐系统的功能
  • 《jQuery Cookbook中文版》——1.11 删除DOM元素
  • 移动App性能测评与优化1.3 新问题的进一步挖掘
  • 《Python自然语言处理》——第1章 语言处理与Python 1.1 语言计算:文本和词汇...
  • 《Android 3D游戏开发技术宝典——OpenGL ES 2.0》——1.5节Android应用程序运行的机制...
  • 《精通软件性能测试与LoadRunner最佳实战》—第2章2.2节性能测试需求分析
  • 《Windows Server 2012活动目录管理实践》——2.5 常见问题
  • 《SQL初学者指南(第2版)》——第2章 基本数据检索
  • 《CCNA学习指南:Cisco网络设备互连(ICND2)(第4版)》——1.1节理解VLAN 和VLAN Trunk 及排除相关故障...
  • 《Redis入门指南》一4.6 节省空间
  • [译] React v16.8: 含有Hooks的版本
  • ➹使用webpack配置多页面应用(MPA)
  • Computed property XXX was assigned to but it has no setter
  • github从入门到放弃(1)
  • Iterator 和 for...of 循环
  • JSDuck 与 AngularJS 融合技巧
  • Linux快速复制或删除大量小文件
  • passportjs 源码分析
  • spring boot下thymeleaf全局静态变量配置
  • Swift 中的尾递归和蹦床
  • vue-loader 源码解析系列之 selector
  • 构建二叉树进行数值数组的去重及优化
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 基于组件的设计工作流与界面抽象
  • 简单实现一个textarea自适应高度
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 前端 CSS : 5# 纯 CSS 实现24小时超市
  • 日剧·日综资源集合(建议收藏)
  • 这几个编码小技巧将令你 PHP 代码更加简洁
  • ionic异常记录
  • 选择阿里云数据库HBase版十大理由
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #使用清华镜像源 安装/更新 指定版本tensorflow
  • (10)STL算法之搜索(二) 二分查找
  • (4)STL算法之比较
  • (二)WCF的Binding模型
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • (十七)Flask之大型项目目录结构示例【二扣蓝图】
  • (四)Linux Shell编程——输入输出重定向
  • (一一四)第九章编程练习
  • (转)Groupon前传:从10个月的失败作品修改,1个月找到成功
  • .Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置
  • .net6Api后台+uniapp导出Excel
  • .NetCore项目nginx发布
  • .NET多线程执行函数
  • .NET牛人应该知道些什么(2):中级.NET开发人员
  • .ui文件相关
  • @Mapper作用
  • @NestedConfigurationProperty 注解用法