Java集合入门总结

本文记录Java集合学习笔记

目录1,Java集合类介绍

Java集合类介绍
Java集合类架构层次
Java集合类应用
Java集合类操作

集合类主要负责保存、盛装其他数据,因此集合类也被称为容器类。相比数组,当需要保存一个可以动态增长的数据(在编译时无法确定具体的数量),java的集合类就是一个很好的设计方案了。

集合接口分为:Collection和Map。list、set实现了Collection接口

Collection和Map的区别在于容器中每个位置保存的元素个数:

Collection 每个位置只能保存一个元素(对象)
Map保存的是"键值对",就像一个小型数据库。我们可以通过"键"找到该键对应的"值"

2,Java集合类架构层次



3,Java集合类应用

1)Set

HashSet

 equals()决定是否可以加入HashSet、而hashCode()决定存放的位置,它们两者必须同时满足才能允许一个新元素加入HashSet

如果两个对象的hashCode相同,但是它们的equlas返回值不同,HashSet会在这个位置用链式结构来保存多个对象。而HashSet访问集合元素时也是根据元素的HashCode值来快速定位的,这种链式结构会导致性能下降。

LinkedHashSet

HashSet的子类,根据元素的hashCode值来决定存放位置,同时使用链表维护元素的次序,看起来是以插入的顺序保存的,遍历时会按照添加顺序访问。

TreeSet

使用红黑树的数据结构来存储集合元素

1. 自然排序:
TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间的大小关系,根据红黑树结构找到它的存储位置,然后将集合元素按升序排序,即自然排序。如果试图把一个对象添加到TreeSet时,则该对象的类必须实现Comparable接口,否则程序会抛出异常。

如果两个对象通过compareTo(Object obj)方法比较相等,新对象将无法添加到TreeSet集合中(牢记Set是不允许重复的概念)。

2.定制排序:

在创建TreeSet集合对象时,提供一个函数式接口Comparator的对象与该TreeSet集合关联,负责集合元素的排序逻辑。

EnumSet

在内部以位向量的形式存储,以枚举值在Enum类内的定义顺序来决定集合元素的顺序。

各Set实现类的性能
1,只有当需要保持一个排序的Set时,才应该使用TreeSet,否则都应该使用性能总是比TreeSet好的HashSet。
2,LinkedHashSet对于普通的插入、删除操作比HashSet慢,但遍历更快。
3,EnumSet是所有Set中性能最好的,但只能保存同一个枚举类的枚举值作为集合元素。
4,这三个实现类都是线程不安全的,通常可以使用Collections工具类的synchronizeSortedSet方法来包装该Set集合,此操作最好在创建时进行。


2)List

有序,可重复,允许插入null对象,使用索引来访问指定位置的集合元素其判断两个对象只要通过equals()方法比较返回true即可。

List实现了Iterator接口的子接口ListIterator,在Iterator基础上增加了如下方法:

boolean hasPrevious()
Object previous()
void add(Object o):在指定位置插入一个元素

List另外提供了一个listIterator()方法,返回一个ListIterator对象。

ArrayList和Vector实现类

都是基于数组实现的List类,initialCapacity参数来设置该数组的长度,默认长度为10 。当添加大量元素时,可以使用ensureCapacity(int minCapacity)方法一次性增加initialCapacity大小,

void trimToSize():调整集合的Object[]数组长度为当前元素的个数,以减少占用的存储空间。

Vector是古老的集合,是线程安全的,但是具有很多缺点,应尽量避免使用。

即使需要保证LIst集合线程安全,也不推荐使用Vector,可以用Collections工具类包装ArrayList变成线程安全的。

Vector还有一个Stack子类,LIFO容器。也是一个古老的集合,需要栈结构时可以使用ArrayDeque代替。


3)Queue集合

Queue用于模拟队列这种数据结构,通常是FIFO容器,Queue接口只有一个PriorityQueue实现类,除此之外还有一个Deque接口,Deque代表一个双端队列,也可以当成栈来使用,Java为Deque提供了ArrayDeque和LinkedList实现类

PriorityQueue

时一个比较标准的队列实现类,其保存队列元素的顺序时按队列元素的大小进行重新排序。不允许插入null元素,排序方式有自然排序和定制排序,基本和TreeSet一致。

ArrayDeque

基于数组实现的双端队列,ArrayList和ArrayDeque两个集合类的实现机制基本相似创建Deque时同样可指定一个numElements参数,指定Object[]数组的长度;默认长度为16;

LinkedList

同时时List和Deque的实现类,和ArrayList、ArrayDeque完全不同,它内部是使用链表的形式来保存集合中的元素,因此随机访问性能较差,但在插入、删除元素时性能比较出色。总体上来说ArrayList性能比LinkedList要好,大部分时候都考虑使用ArrayList。

使用List集合的建议:
-如果需要遍历,对于ArrayList、Vector集合应该使用随机访问方法(get);对于LinkedList则更应使用迭代器(Iterator)。
-频繁插入、删除则考虑使用LinkedList,使用ArrayList、Vector集合需要经常重新分配内部数组。
-多线程访问可以考虑使用Collections将集合包装成线程安全的集合

注意:所有内部基于数组的集合实现,如ArrayList、ArrayDeque等,使用随机访问的性能比使用Iterator迭代访问的性能要好,因为随机访问会被映射称对数组元素的访问

4)Map

Map包含了一个keySet()方法,用于返回Map里所有kay组成的Set集合。

还提供了一个Entry内部类来封装kay-value对,而计算Entry存储时只考虑Entry封装的key。

HashMap和Hashtable

其两者关系完全类似于ArrayList和Vector,Hashtable不允许使用null作为key和value,HashMap不允许有key相同,所以只能有一对key-value的key为null(就像Set)。

LinkedHashMap

HashMap的子类,使用双向链表来维护key-value对的次序

Properties读写属性文件

Hashtable类的子类,其key和value都只能是字符串类型。相当于key、value都是String类型的Map;

SortedMap接口和TreeMap实现类,如SortedSet和treeSet一般

WeakHashMap实现类,和HashMap的用法基本相似,但是WeakHashMap的key只保留对实际对象的弱引用。

IdentityHashMap实现类

和HashMap基本相似,但是当且仅当两个key严格相等(key1 == key2)时,才认为两个key相等,对于普通的HashMap而言,只需要key通过equals()方法比较返回true,且它们的hashCode值相等即可

EnumMap实现类

在内部以数组形式保存,不允许null作为key,但可作为value。

一般使用HashMap,其正是为快速查询设计的,底层其实是采用数组来存储key-value对,但如果需要一个总是排好序的Map时,使用TreeMap。

4,Java集合类操作

使用Iterable遍历

Java 8为Collection的父接口Iterable接口新增了一个forEach(Consumer action)默认方法,Consumer是一个函数式接口,accept(T t)方法是该接口中唯一的抽象方法。

使用Iterator遍历

Iterator主要用于遍历Collection集合中的元素,Iterator对象也被称为迭代器。其定义了4个方法:

boolean hasNext()
Object next()
void remove()
void forEachRemaining(Consumer action)

Java 8为Iterator新增的forEachRemainin(Consumer action)方法所需的Consumer参数同样也是函数式接口。

 当使用Iterator对集合元素进行迭代时,Iterator并不是把集合元素本身传给了迭代变量,而是把集合元素的值传给迭代变量,所以修改迭代变量的值对集合的元素本身没有任何影响。 并且迭代访问时,Collectio集合里的元素不能被改变,只有通过Iterator的remove()方法删除上一次next()方法返回的集合元素才可以;否则会引发java.util.concurrent.ModificationException异常。

使用Predicate 操作集合

Java 8为Collection集合新增了一个removeIf(Predicate filter)方法,该方法将会批量删除符合filter条件的所有元素,例如

collection.removeIf(ele -> ((Stirng)ele).length() < 10); //将删除长度小于10的字符串集合元素

使用Stream操作集合

Stream、IntStream、LongStream、DoubleStream等流式API,这些API代表多个支持串行和并行聚集操作的元素;

Java还为每个流式API提供了对应的Builder,可以使用对应的Builder来创建对应的流。

独立使用Stream的步骤如下:
-使用Stream的builder()类方法创建对应的Builder。
-重复调用Builder的add()方法向该流中添加多个元素。
-调用Builder的build()方法获取对应的Stream。
-调用Stream的聚集方法。

聚集方法分为

-中间方法(intermediate):中间操作允许流保持打开状态,可直接调用后续方法,中间方法返回的是另一个流;
-末端方法(terminal):末端方法是对流的最终操作,执行之后该流会被消耗,不再可用。


主要参考《疯狂Java讲义》,本人才疏学浅,如有错误烦请各位大佬指点


另外菜鸟的这篇教程通过接口,实现类,算法三个层次去分析集合,写的很不错。Java 集合框架菜鸟教程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值