编程思想是相通的,只是实现方式有所不同。
数据库中,我们常常用索引来找到具体某个值,当然会经常用联合索引。而在开发中,常常会有种情况:集合的key使用自定义类对象,需要自己实现hashCode()和equal()方法。
再来看看Map、List、Set等集合的实现:
一、Map,以hashMap为例,
1)初始化为长度16的数组,数组每个元素为一个链表对象。
2)当新建链表元素个数超过threshold,数组长度就扩展2倍。
3)当put时候,用if (e.hash == hash && ((k = e.key) == key || key.equals(k))) 来判断是否(Object) key相等。
int threshold = (int)Math.min(capacity(16) * loadFactor(0.75f), MAXIMUM_CAPACITY(1 << 30) + 1);
另外,在java8中,HashMap加入了红黑树结构,当链表元素较多(默认8个)时,链表就会转化为红黑树。
而TreeMap实现也是基于红黑树的。可参考
TreeMap:由红黑树实现,与HashMap不同,他内部元素不是数组,而是一个树型结构。身为排序二叉树,所以他是有序的。
二、List,以ArrayList为例,
1)初始化为长度10的数组,数组每个元素为一个Object。
2)当新添加对象的坐标index大于数据长度,就扩展增加当前数组1/2的长度。
3)当add时候,已有对象的size++,超过数组长度就扩展,当调用set(int index, E element)方法时,传值大于新添加对象的坐标时会报错。
三、Set,以hashSet为例,
1)其实用一个HashMap成员变量来实现,所以特性和hashMap基本一致。
而其他Set实现类等也是如此,比如TreeSet用TreeMap实现。
并发:
1、可以使用concurrent包下面的类,比如ConcurrentHashMap<K, V>和CopyOnWriteArrayList<E>等。
2、自己加锁并发。其中用Iterator遍历时,增删元素时也需要对集合加锁。
jdk1.7以及之前版本ConcurrentHashMap实现:Segment锁分段。每个Segment下面是多个Node,jdk7是Segment+HashEntry。
jdk1.8版本ConcurrentHashMap实现:采用Node + CAS + Synchronized,有点像java8的hashmap,使用数组+链表+红黑树,保留锁分段思想。使用较多CAS算法(即unsafe.compareAndSwapInt(this, valueOffset, expect, update)),这样可非阻塞无锁插入,但在默认操作hash值相同的链表还是会synchronized头结点上锁,将新值放在node最后一个后面,这样才能保证线程安全,和以前一样。
put方法:1.6直接获取锁,1.7自旋锁(UNSAFE.get),等待其他人操作完,1.8是链表为null直接cas乐观锁,否则Node链表加锁。
get方法:1.6乐观锁,直接获取值,为null则可能正处于put,需要再加过判断一次。1.7HashEntry的乐观锁(UNSAFE.get)。1.8Node的乐观锁(UNSAFE.get)。
针对:
get操作的高效之处在于采用分段锁,且整个get过程不需要加锁,除非读到的值是空的才会加锁重读,特性如下:
1、写用分段锁:每个Segment包含一个数组元素,每个元素是一个HashEntry<K,V>的链表,而且put添加元素时放在头部,不影响读取。至于remove中间元素,会设置链表元素的next属性(volatile修饰)。
2、get操作不加锁:get方法里将要使用的共享变量都定义成volatile,如用于统计当前Segement大小的count字段和用于存储值的HashEntry的value。定义成volatile的变量,能够在线程之间保持可见性,能够被多线程同时读,并且保证不会读到过期的值,但是只能被单线程写(有一种情况可以被多线程写,就是写入的值不依赖于原值),在get操作里只需要读不需要写共享变量count和value,所以可以不用加锁。之所以不会读到过期的值,是根据java内存模型的happen before原则,对volatile字段的写入操作先于读操作,即使两个线程同时修改和获取volatile变量,get操作也能拿到最新的值,
static final class HashEntry<K,V> { final int hash; final K key; volatile V value; volatile HashEntry<K,V> next; HashEntry(int hash, K key, V value, HashEntry<K,V> next) { this.hash = hash; this.key = key; this.value = value; this.next = next; } }
相关推荐
本篇文章将详细介绍如何将Map和List集合转换为XML字符串,以及如何将XML字符串反向转换回Map和List集合。 首先,让我们探讨`Map`集合转成XML字符串的过程。一个`Map`对象存储键值对,可以使用各种库如`JAXB (Java ...
本主题聚焦于易语言中的面向对象编程,特别是模仿Java集合框架的List和Map接口的实现。这些数据结构在编程中扮演着核心角色,用于组织和管理数据。 首先,让我们深入了解易语言的面向对象编程概念。面向对象编程...
Map拆分与List拆分涉及到数据的分布式处理,这通常在Hadoop、Spark等大数据处理框架中常见。下面我们将详细探讨这两个概念及其在实际应用中的重要性。 首先,Map是一种键值对存储的数据结构,其中每个键(Key)都是...
首先新建一个实体类Person @Data public class Person { /** 编码 */ private String code; /** 名字 */ ...实例化三个对象放入list集合中 public static void main(String[] args) { Person pe
5. **返回新的List<Map>**:最终返回包含Map对象的List集合。 #### 示例代码: 假设有一个AnnouncementBean类,包含属性:actid(ID),acttitle(标题),actcon(内容),acttime(时间),usid(发布人),...
2. 便于数据展示:List<Map> 可以方便地将查询结果集展示在 GUI 组件中,如 JTable、DataGridView 等。 在实际开发中,我们可以根据需要对 ResultSetToList 方法进行修改和扩展,以满足不同的业务需求。 知识点: ...
详细描述map、list、set的常用子类特性,各个场景的适用。
List集合转换成String,String转List,Map转String,String转Map等 集合与字符串相互转换,可以自己扩展源码,带有注释
在Java 8中将List转换为Map对象方法 在Java 8中,将List转换为Map对象是一种非常实用的技术,特别是在处理大规模数据时非常有用。本文将详细介绍在Java 8中将List转换为Map对象的方法,并提供了多种实现方式。 ...
### 集合概述:set、List、Map #### 一、集合框架概述 ##### 1.1.1 容器简介 在Java编程中,集合框架是一个非常重要的概念,它提供了一种灵活的方式来存储、操作和管理不同类型的对象集合。集合框架的主要目标是...
通过正确配置Ajax请求和服务器接口,你可以轻松地传递和处理List、Map等复杂数据结构,提升Web应用的交互体验。在实际项目中,确保对错误处理和安全性有充分考虑,这将有助于构建健壮和安全的Web应用。
例如,我们可以有一个用户信息的Map,其中键是用户ID,而对应的值是一个包含用户名、邮箱等信息的另一个Map。 ```java Map, Map, String>> users = new HashMap(); ``` 获取嵌套Map的key和value通常涉及两个步骤:...
常见的集合映射类型有 Set、List、Array、Map 和 Bag 等,每种类型都有其特点和应用场景。 Set 集合映射 Set 集合是 Hibernate 中基础的集合类型,元素数据一般使用外键同主表关联。Set 集合非常适用于集合元素不...
(数组 list集合 map集合 Object对象 XML数据格式) 转成 string json
根据给定文件的信息,我们可以详细地探讨一下Java中几种主要的集合容器——List、Set以及Map的区别,并且深入了解它们各自的特性和应用场景。 ### 一、List #### 1. ArrayList - **特点**:`ArrayList`是基于动态...
在Java编程语言中,集合框架是处理对象组的重要工具,其中List、Set和Map是最基本的接口,分别代表了有序的列表、无序的集合和键值对的映射关系。下面将详细解释这些集合类及其特点。 1. **List接口**: List是一...
list转map的测试类,用到jdk1.8的新特性,感觉用起来很方便
在Java中,Map是一种存储键值对的数据结构,而List则是一个有序的元素集合。Map不能直接转换为List,但可以通过一些方法实现。一种常见的方式是创建一个新的List,然后遍历Map的entrySet(),将每个键值对作为新List...
本文将深入探讨Java集合框架中的四个主要接口:Collection、List、Set和Map,以及它们的实现原理。 ### 集合框架概述 集合框架是Java API中用于存储和管理对象的统一框架。它为数据结构提供了抽象接口,使得程序员...
在Hibernate的映射文件(.hbm.xml)中,我们通常使用`<set>`, `<list>`, `<map>`等标签来定义集合映射。每个标签都有对应的属性,例如: - `name`: 对象属性名。 - `table`: 所映射的数据库表名。 - `inverse`: ...