强推!京东大佬熬了一夜手写的Java集合详解笔记,牛客网超万下载

219 阅读9分钟

Hello,今天给各位童鞋们分享的是Java集合,赶紧拿出小本子记下来吧

image.png

Java中的集合

集合:能够动态存放多个数据的存储结构,Java提供的一个公共API,存在于java.util包中

Java整个集合的架构如下:

image.png 主要有两个分支:

  • Collection 每次只能存入一个值 具体的存储性质和不同的子接口有关

Set 存入的元素无序且不重复 常用实现类有:

  1. HashSet 无序不重复的集合
  2. LinkedHashSet 有序不重复的集合 有序是通过链表方式实现

List 存入的元素有序且可以重复 常用实现类有:

  1. ArrayList 底层以数组方式实现 特点 读取效率高 但修改的效率较低 经常使用ArrayList
  2. LinkedList 底层以双向链表实现实现 特点 修改的效率高 但读取效率较低

Map 每次需要存入一个键值对

常用实现类 HashMap

Collection

image.png

Iterator

Iterator 是Collection的父级接口 内部提供了对于Collection类型的集合的遍历方式

常用方法:

  • hasNext() 查看当前指针的下一个位置是否有元素 如果有返回true 否则返回false
  • next() 移动指针到下一个元素 并获取该元素 返回给调用者
  • remove() 移除当前遍历的指针

自从JDK5开始,所有Iterator方式实现的变量都可以使用 forEach方式来进行遍历

Set接口

Set接口是Collection的一个子接口类型,它的特点是无序且不重复

Set集合与数学中“集合”的概念相对应

如何判定Set中的元素是否重复:

  1. 判定该对象的hashCode()方法返回的值是否相等 如果相等即判定当前两个对象相等 直接跳过该对象的存储步骤 如果不等则直接存入元表中
  2. 当hashCode() 返回的值相等时 再利用对象的equals()方法来判定当前两个对象是否相等 如果相等则跳过该存储不走 如果不等 则会将该存储的模块转换为链表形式进行存储 在JDK8后如果链表的长度达到8 则会将链表转换成一个红黑树结构进行存储 但此种方式很少会触发

根据对象的哈希码值计算出它的存储索引,在散列表的相应位置(表元)上的元素间进行少量的比较操作就可以找出它。

Set系的集合存、取、删对象都有很高的效率。

对于要存放到Set集合中的对象,对应的类一定要重写equals()和hashCode(Object obj)方法以实现对 象相等规则

常用子接口:

  • HashSet 不保存元素的存入顺序

底层是使用Hash表的形式进行存储数据的,所以读取效率较高,直接根据hash值读取对应的数据

  • LinkedHashSet 底层是链表 保证存入顺序 但依然不能重复

需要有序且不重复时使用 但效率略低

List接口

实现List接口的集合类中的元素是有序的,且允许重复。

List集合中的元素都对应一个整数型的序号记载其在集合中的位置,可以根据序号存取集合中的元素。

JDK API所提供的List集合类常用的有:

  • ArrayList
  • LinkedList

常用的方法:

public Object get(int index) 返回列表中的元素数

public Object add(int index, Object element); 在列表的指定位置插入指定元素.将当前处于该位置的

元素(如果有的话)和所有后续元素向右移动

public Object set(int index, Object element) ; 用指定元素替换列表中指定位置的元素

public Object remove(int index) 移除列表中指定位置的元素

public ListIterator listIterator() 返回此列表元素的列表迭代器

remove(Object obj) 如果obj存在则直接移除

remove(int index) 移除指定位置处的元素 并将元素返回给调用者

ArrayList

使用数组结构实现的List集合

image.png

优点:

  • 对于使用索引取出元素有较好的效率
  • 它使用索引来快速定位对象

缺点:

  • 元素做删除或插入速度较慢
  • 因为使用了数组,需要移动后面的元素以调整索引顺序、

LinkedList

LinkedList是使用双向链表实现的集合。 LinkedList新增了一些插入、删除的方法。

image.png 优点:

  • 对频繁的插入或删除元素有较高的效率
  • 适合实现栈(Stack)和队列(Queue)

缺点:

读取数据只能某一方向依次遍历查找 效率较低

Map

在集合中,Map和Collection是一个并列的关系,它内部职能存储键值对(key-value)。且key的值不能重 复且是无序的,value无要求。

JDK API中Map接口的实现类常用的有:

  • HashMap 内部使用哈希表对 “键-值”映射对 进行散列存放。

​ 1.使用频率最高的一个集合。

LinkedHashMap 是HashMap的子类

​ 1.使用哈希表存放映射对

​ 2.用链表记录映射对的插入顺序。

Map实现类中存储的“键-值”映射对是通过键来唯一标识,Map底层的“键”是用Set来存放的。 所以,存入Map中的映射对的“键”对应的类必须重写hashcode()和equals()方法。常用String作为Map 的“键”。

Map接口常用方法:

image.png

遗留类

Vector

旧版的ArrayList,它大多数操作跟ArrayList相同,区别之处在于Vector是线程同步的。

它有一枚举方式可以类似Iterator进行遍历访问,也可以使用forEach或者Enumcation(JDK1.0用来遍历 集合,后面不推荐使用可以用Iterator替代)

Stack

•Stack类是Vector的子类,它是以后进先出(LIFO)方式存储元素的栈。线程同步的。

Stack类中增加了5个方法对Vector类进行了扩展

image.png Hashtable

旧版的HashMap,JDK1.0中创建的,在JDK2.0中使用HashMap替换Hashtable,本身具有线程同步的 功能。

使用方式和HashMap大致一样。

Properties

Hashtable的一个子类,用于获取当前项目中的配置文件中的信息,该类没有泛型 所有的key-value均 为String类型

Properties类表示了一个持久的属性集。Properties可保存在流中或从流中加载。属性集中每个键及其 对应值都是一个字符串。

不建议使用 put 和 putAll 这类存放元素方法,应该使用 setProperty(String key, String value)方法,因 为存放的“键-值”对都是字符串。类似取值也应该使用getProperty(String key)。

image.png

排序接口

TreeSet & TreeMap

在集合中存在一个自动排序的存储集合,底层使用红黑树进行数据存储。

只要存入该集合中的数据都会按照排序规则进行默认排列

对于数据类型的包装类 以及 String类型 默认都实现了排序接口 会按照字典顺序进行数据排列

如果希望元素放置在TreeSet或者TreeMap中 则该对象必须实现比较接口Comparable 否则在存放时会 抛出异常

Comparable

比较接口,所有需要实现排序规则的对象都应该实现该接口,表示该类时一个可比较类。

实现Comparable时需要实现其CompareTo(Object o) 方法

按照升序进行判定规则:

a.age > b.age 需返回 正整数

a.age < b.age 需返回 负整数

a.age == b.age 需返回 0

按照降序排列则只需将正整数和负整数的位置交换即可

优点:无序另外设置排序规则,在可排序的方法中可以直接进行排序

缺点:在一个项目中如果实现Comparable 则该对象默认只能有一种排序方式

image.png Comparator

比较器接口,可以自定义一个类来实现Comparator接口,并实现其compare(Object o1,Object o2)方 法

比较规则和Comparable中的规则一致。

优点:在一个项目中可以按照不同的需求定义不同的比较器,在具体需求出使用精准的比较规则来进行 数据排序

缺点:在使用时需要手动告知排序接口排序规则(设置参数),如果仅使用一次则见识使用匿名内部类 或Lambda表达式来实现

当一个对象即实现了Comparable接口 用有Comparator类型的排序类 则如果显示调用Comparator的 排序类 会覆盖Comparable的实现规则 否则直接使用Comparable的默认排序

image.png

Collections

针对于集合专门设计的工具类,提供了集合常用的功能,方便开发者提升开发效率。

常用方法:

void sort(List list) 根据元素的自然顺序 对指定List列表按升序进行排序。List列表中的所有元素都必 须实现 Comparable 接口。 void shuffle(List list) 对List列表内的元素进行随机排列 void reverse(List list) 对List列表内的元素进行反转 void copy(List dest, List src) 将src列表内的元素复制到dest列表中 List synchronizedList(List list) 返回指定列表支持的同步(线程安全的)列表

集合类的线程安全

集合类大多数默认都没有考虑线程安全问题,程序必须自行实现同步以确保共享数据在多线程下存取不 会出错:

使用同步锁

synchronized(list){ list.add(…); }

用java.uitl.Collections的synchronizedXxx()方法来返回一个同步化的容器对象

•List list = Collections.synchronizedList(new ArrayList());

这种方式在迭代时仍要用synchronized修饰

image.png 从JDK5.0开始,提供了一个concurrent包,专门提供了一些在并发操作中好用的对象。跟集合相关的常 用对象有:

  • ConcurrentHashMap
  • CopyOnWriteArrayList
  • CopyOnWriteArraySet

以上的对象在同步性和效率性上进行了平衡,只在修改元素时加锁,在读取元素时不上锁,提高读取效 率,适合使用于并发性强且不长修改的数据。

好啦,今天的文章就到这里了,希望能够帮助到屏幕前迷茫的你们