首页 > 编程知识 正文

JAVA容器,java是什么

时间:2023-05-06 13:23:59 阅读:40603 作者:736

Java实用类库为解决许多具体问题提供了相当完整的容器。 因为我自己是安卓开发者,包括我在内的很多安卓开发者,最擅长的就是listview(recycleview ) BaseAdapter ArrayList三剑客,平时接触使用的容器也只有ArrayList和HashMap 整个Java容器体系的掌握和使用还停留在浅水平。 没有改善的余地,跟着我总结一下关于Java容器的知识吧。

结构java容器类的继承结构

具体介绍List

设置

队列

迭代器

收集

地图

一些建议

高级并发容器复制写入程序列表和一次写入时复制策略

ConcurrentLinkedQueue

并发散列映射和锁定分段技术

堵塞队列

java容器类的继承结构

Java容器类库定义了两个不同概念的容器: Collection和MapCollection。 这些容器都遵循一个或多个规则。 List必须按照插入顺序保存元素。 Set不能包含重复元素。 队列根据队列规则确定对象生成的顺序。

(本文中Jdk源代码版本无特殊说明,均为jdk1.8.0_101 ) publicinterfacecollectionextendsiterable (intsize ); 布尔isempty (; 布尔内容(objecto; 迭代器迭代器(;

对象[ ] to array (;

t [ ]到阵列(t [ ] a ); 布尔添加(ee; 布尔移除(对象); booleancontainsall (Java.util.collection c ); boolean addall (Java.util.collectionextendsec; 布尔移动全部(Java.util.collection c;

…//省略了其他方法

}

java定义了Collection接口和内部集合的基本操作方法,Collection默认情况下可以在集合的末端添加元素或删除指定的元素。 List、Set和Queue接口都是从Collection继承的,每个接口都有不同的定义。 在映射对的“键-值对”对象中,可以使用键来搜索值。

publicinterfaceMap{intsize (; booleancontainskey (对象密钥); booleancontainsvalue (对象值; vget (对象密钥); vput(kkey,Vvalue ); v remove (对象密钥); voidputall (Java.util.mapextendsk? 扩展虚拟机; 语音清除(; 安全设置(; Collectionvalues (;

SetentrySet (; 接口条目{ kget key (); VgetValue (; 电压设置值(电压值); 布尔表达式(对象); inthashCode (;

.

}布尔表达式(对象); inthashCode (;

}

Map内部接口Entry对应于Map的键-值对。

具体介绍

迭代器

先介绍一下迭代器。 迭代器本身也是publicinterfaceiterator { boolean hasnext (; Enext (; defaultvoidremove ((thrownewunsupportedoperationexception ) (remove );

} defaultvoidforeachremaining (咨询服务) )

objects.require nonnull (动作;

while (hasNext())

action.accept(next());

}

}通过容器的iterator()方法拿到容器的迭代器

迭代器的next()获取下一个元素

hasNext()判断是否还有元素

remove()删除指定元素

ListIterator

ListIterator是Iterator的扩展之内,用于各种List类访问,支持双向移动。

Collection

List

List 承诺可以将元素维护在特定的序列中.List接口在Collection的基础上添加了大量的方法,使得可以再List中间插入和移除元素。public interface List extends Collection {

...        boolean add(E e);        boolean remove(Object o);        boolean containsAll(Collection> c);        boolean addAll(Collection extends E> c);        boolean addAll(int index, Collection extends E> c);        boolean removeAll(Collection> c);        boolean retainAll(Collection> c);        E get(int index);        E set(int index, E element);        void add(int index, E element);        E remove(int index);        int indexOf(Object o);        int lastIndexOf(Object o);

java.util.List subList(int fromIndex, int toIndex);

...

}

有两种类型的List,ArrayList和LinkedListList类型优点缺点底层实现ArrayList随机访问元素较快中间元素的插入和删除较慢数组

LinkedList中间元素的插入和删除,顺序访问的优化随机访问元素较慢双向链表

Set

Set不保存重复的元素,通常用于快速查找元素。值得一提的是,Set具有与Collection完全一样的接口,没有任何额外的功能。 存入的元素必须定义equals()方法Set类型使用场景底层实现HashSet快速查找,元素必须定义hashCode()链表

TreeSet保持次序,元素必须实现Comparable接口红-黑树结构

LinkedHashSet维护次序的HashSet, 元素必须定义hashCode()链表

Queue

除了并发应用,Queue仅有的两个实现是LinkedList和PriorityQueue, 其中LinkedList同时实现了List, Deque接口。它们的差异在于排序行为而不是性能。public interface Queue extends Collection {        boolean add(E e);        boolean offer(E e);        E remove();        E poll();        E element();        E peek();

}

MapMap类型使用场景底层实现HashMap快速查询散列表

LinkedHashMap迭代遍历具有顺序(插入顺序 or 最近最少使用)链表

TreeMap具有排序,唯一可以返回子树的Map(subMap())红-黑树结构

弱键映射,映射之外无引用的键,可以被垃圾回收散列表

ConcurrentHashMap线程安全的Map链表

IdentityHashMap使用==代替equals()对键进行排序,专位解决特殊问题链表

我们可以手工调整HashMap来调整性能,涉及到如容量、初始容量、尺寸、负载因子等概念。感兴趣的话可以看一些相关资料。

一些建议不要使用过时的容器 如Vector Enumeration Hashtable Stack(没错,这就是java最初的糟糕设计,实际中使用栈的话推荐LinkedList)

进阶·并发容器

这里不会讨论的太细致的实现,仅仅简单介绍一下基础知识,感兴趣的可以阅读《Java 并发编程的艺术》这本书。

CopyOnWriteArrayList与Copy-On-Write策略

Copy-On-Write简称COW,是一种用于程序设计中的优化策略。其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改,这是一种延时懒惰策略。从JDK1.5开始Java并发包里提供了两个使用CopyOnWrite机制实现的并发容器,它们是CopyOnWriteArrayList和CopyOnWriteArraySet。CopyOnWrite容器非常有用,可以在非常多的并发场景中使用到。CopyOnWrite容器即写时复制的容器。通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。

CopyOnWrite容器只能保证数据的最终一致性,不能保证数据的实时一致性。所以如果你希望写入的的数据,马上能读到,请不要使用CopyOnWrite容器。

ConcurrentLinkedQueue

在并发编程中,有时候需要使用线程安全的队列或列表。通常实现线程安全有两种方式,一种是使用阻塞算法,一种是使用非阻塞算法。非阻塞算法实现基础为循环CAS(Compare and Swipe 比较和交换)。

ConcurrentLinkedQueue技术上的实现与CopyOnWriteArrayList与Copy类似,但是容器只有部分内容而不是整个容器可以被复制和修改。ConcurrentLinkedQueue有head节点和tail节点组成,每个节点由节点元素(item)和指向下一个结点(next)的引用组成。节点之间通过next关联起来,形成一张链表结构的队列。

ConcurrentHashMap与锁分段技术

ConcurrentHashMap是线程安全且高效的HashMap。多线程环境下,使用非线程安全的HashMap会导致死循环,而如文章中建议的那样,HashTable这种过时容器效率低下(使用synchronized来保证线程安全)。ConcurrentHashMap使用锁分段技术,大大提高了并发使用的效率。锁分段技术: 假设容器有多把锁,每一把锁用于锁容器其中一部分数据,当多线程访问容器不同数据段数据时,线程间就不存在锁竞争,从而提高并发访问效率。

阻塞队列

JDK7 提供了7个阻塞队列,实现原理都是基于生产-消费模式的等待通知机制。阻塞队列类型特点ArrayBlockingQueue由数组结构组成的有界阻塞队列

LinkedBlockingQueue由链表结构组成的有界阻塞队列

PriorityBlockingQueue支持优先级排序的×××阻塞队列

DelayQueue使用优先级队列实现的×××阻塞队列

SynchronousQueue不储存元素的阻塞队列

LinkedTransferQueue由链表结构组成的×××阻塞队列

LinkedBlockingQueue由链表结构组成的双向阻塞队列

感谢阅读~

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。