说明

这是一个完善了但又不完善的笔记,或许以后会更新

可以参考但请务必超越

源文件


Tools


Typora
PicGo

Java集合

集合呢,严格来讲这篇文章只是初始,接下来处处都会涉及相关,一篇一篇的讲述其中的表表树树

但后面也不再会讲这篇文章的内容,所以还是要认真学习

集合框架及背后的数据结构

接下来就先来大致了解

1.简介

Java Collection Framework直译Java集合框架,又被称为容器container,是定义在java.util包下的一组接口interfaces和实现类classes

说白了,就是官方整合提供给开发者使用的一套工具

既然定义在java.util包,那就是说后面都需要导入这个包来用

其主要表现为将多个元素element置于一个单元中,用于对这些元素进行快速、便捷的存储 tore、检索retrieve 、管理 manipulate,即平时我们俗称的增删查改CRUD

官方教程,可以存着

较为重要的总览表,后面会围绕这张图分篇讲其中的内容

类和接口总览

  • interface:接口,对一个行为的“抽象”,代表着一个标准,每一个接口都有自己的标。Iterable如果已经实现了这个接口,那么这个类就可以使用增强for循环也就是foreach()来遍历这个集合
  • abstract class:抽象类
  • class:具体的实现类

这张图列举了较为重要的接口、抽象类和实现类(当然不可能是所有的)

其中ListQueueSetDeque是最重要的四个功能

四个接口

List:实现这个接口的多半都是线性结构(线性表,比如顺序表、链表、栈和队列)

Queue:队列,本身其实也属于线性结构,但是为什么分开了?因为有一种队列不是线性的,优先级队列,下面是一颗二叉树

Deque:双端队列

Set:元素不能重复的集合,实现这个接口的类里面元素不能重复

队列、双端队列和优先级队列

队列就像是食堂打饭、买车票或者握手会等排队,队尾进队头出

双端队列嘛,那就是队头队尾都可以进出。(不过一般插队死的不太好看)

当然这里举栗牵扯到排队,那就还会出现一种队列,优先级队列

PriorityQueue:优先级队列,每个元素都具备优先级,底层是一个二叉树

医院车站有军人优先什么的,或者巴基斯坦车站有中国人优先。不过希望各位人类不要做非人类的事情,死的不会太好看。

说的有点多,还是举程序的栗子吧。在使用移动端进行游戏的过程中突然来了电话,那就会优先接听电话,或者用户可以自定义程序优先级,这就是优先级队列。

Set接口

不能重复元素的集合,这个很好理解

看向下面的SortedSet(sort分类排序),一组有序的不能重复的元素。是Set的扩展,extends set。说明SortedSet不但可以使用自己的功能,还能使用Set的功能

再向下TreeSet,是一个具体的类,extends上面的2个接口功能都可以用。底层是一个红黑树

但是HashSet就没有SortedSet的排序功能。底层是一个哈希表

具体的实现类

剩下的class,可以看到像StackVectorArrayListLinkedList他们都属于线性结构继承于AbstractList,可以使用List接口和AbstractList抽象类

同时LinkedList又实现了Deque接口

Vector在Java当中用的非常少,在C++用的多

Stack就是栈

ArrayList就是顺序表,底下就是个数组嘛

LinkedList比较特殊,背后的数据结构是一个双向链表。同时可以代表双向链表、普通队列和双端队列

map接口

可以看到图中把map单独列了出来,和其他的互不相连,是一个单独的接口。底层是一个key value结构

虽然总览和Set一样,但是Set只能放key没有value

其中的TreeMapHashMap底层也是红黑树和哈希表

HashMapTreeMap

对于这两个东西,只讲HashMap就完事了

  1. TreeMap使用较少
  2. HashMap学会,TreeMap就很简单,就多一个排序功能。

TreeMap虽然不讲,但是,红黑树,B树,AVL树这些底层的数据结构一定会讲

只会多讲,不会少讲

三个工具

还有下面的迭代器,对象比较和工具类这三个,属于是工具

会用即可,用到就会说,也很简单

迭代器遍历集合,对象比较2个讲过,Arrays一直都在用,Collections操作集合,比如排序逆置什么的,可以查手册

这些就不多讲了,直接用,用到就查

2.集合及数据结构的意义

注意,非常重要

学习集合,就必须要学习背后的数据结构

优点和作用:

  • 使用成熟的集合框架,有助于便捷、快速的写出高效、稳定的代码
  • 学习背后的数据结构,有助于理解各个集合的优缺点以及使用场景

2.1 笔试和面试题

面试时,经常会甚至大多数,都会问关于集合和数据结构的问题

可以直接查大厂的面经

腾讯-Java后台开发面经

  1. HashMap了解不,介绍一下,如果一个对象为key时,hashCode和equals方法的用法要注意什么?
  2. HashSet和HashMap的区别是什么?
  3. HashMap是线程安全的么?那需要线程安全需要用到什么?

阿里巴巴-Java后台开发面经

  1. ArrayList和LinkedList的区别是什么?
  2. 有了解过HashMap的具体实现么?
  3. HashMap和ConcurrentHashMap哪个效率更高?

编程题:判断一个链表是否是一个回文链表。

Redis的zset类型对应到java语言中大致是什么类型?

hashCode主要是用来做什么用的?

等等...

3.接口interfaces

之前其实有讲过接口,这次开始就要讲集合和数据结构的接口了

往后的内容全部都是重点

3.1 Collection接口

这个接口相当于是上层的接口,可以引用任何一个实现类,为了理解举栗,可能会使用不太恰当且较少使用的方法

可以看到前面的大部分内容,都在这个接口之下,比如SetListQueueDeque

Collection:用来存储管理一组对象objects ,这些对象一般被称为元素elements

Collection官方文档

还有很多的常用方法,这里就不多讲了,可以查,用到就查

3.2 Collection示栗

我们首先来实例化对象

public static void main(String[] args) {
    Collection collection = new ArrayList();
}

注意当然不能new Collection()

然后就给他赋值嘛。但是有个问题就出现了

collection.add("hello");
collection.add(10);

什么数据类型都能放,可以看到现在是没有报错的

这里就离谱了,这还能放不一样的

那怎么改成一种数据类型呢?

初识泛型

点开Collection,可以看到有个尖括号

泛型是一种较难的语法,这里就先不讲那么深,后续都会慢慢讲

这里先使用就ok

我们可以给Collection指定只能使用String一种类类型

Collection<String>

注意

尖括号中的类型,必须是类类型,也就是说简单的数据类型是不能放的。基本数据类型就需要使用包装类类型

Collection<Integer> collection1 = new ArrayList<>();
collection1.add(10);

方法使用

可以直接打印看看

打印

wtf?打印引用不是应该打印地址吗,怎么就直接打印出来数据了

这说明ArrayList使用了toString,来验证一下

点开ArrayListalt+7或者搜索toString

纳尼,这不是没有吗?

可以看到ArrayList<E> extends AbstractList<E>,那就打开AbstractList看看

没有,接着点开AbstractCollection

这下有了

清空

还可以使用clear清空

collection.clear();

可以看到,给数组的每个元素都置空了

然后size = 0

3.3 Collection注意

既然讲到了泛型,那就要注意一个点

如果涉及到类型转换问题,比如

String[] objects = (String[])collection.toArray(;)

这样即使强转也是不行的,也不建议进行整体的强制类型转换

因为JVM对数组和泛型的处理,数组和泛型之间的一个重要区别是他们如何强制执行类型检查。数组在运行时存储和检查类型信息,泛型在编译时检查

意思就是说你可能只是把整体object强转了,但是其中的元素没有强转

可以暂且理解为:内部的元素并没有全部进行转换。(换汤不换药,换碗不换汤,鸡汤来喽~怎么都不吃?王大队长可别开玩笑)

再深的东西可能需要考古JVM...有兴趣再说吧

3.4 Map接口

可以先打开看看

public interface Map<K,V>

可以看到尖括号内K和V两个值,和前面的Collection一样,必须是引用类型

Map官方文档

方法和其他内容,还是查,用到就查

3.5 Map举栗

put:将指定的K和V放入Map

Map<String, String> map1 = new HashMap<>();
Map<String, String> map2 = new TreeMap<>();

这里就简单举栗了,也不难,但是其中的操作很重要

先存放数组数据

map1.put("黑色剑士", "kirito");
map1.put("闪光", "asuna");

根据K找V

get:根据指定的K查找对应的V

String ret = map1.get("黑色剑士");

getOrdefault:根据指定的K查找对应的V,没有找到就用默认值替代

String ret1 = map1.getOrDefault("封弊者", "桐姥爷");
System.out.println(ret1);

找到了就打印V嘛

查找是否包含

containKeycontainValue:判断是否包含key和value

boolean flg1 = map1.containsKey("狂暴补师");
boolean flg2 = map1.containsValue("asuna");
System.out.println(flg1);
System.out.println(flg2);

打印

当然还要打印看看现在存放的数据

System.out.println(map1);

wtf?为什么先打印了第二个数据

首先说在前面,为了理解,下面会简单的举栗,并不是真正的哈希表结构

哈希在存放元素的时候,会使用哈希函数根据key来存放,相当于加工厂

所以存放的位置,最终的顺序可能就会超出想象

entrySet

entrySet:将所有键值对返回

可能有点超前,不太友好,不过这篇文章是初识,那就没关系了,先接触不深入

Set<Map.Entry<String, String>> entrySet = map1.entrySet();

这个方法会把HashMap里面的数据组装起来,存放到他的空间entrySet中,会比较奇怪,后面再深入讲

这与就可以foreach循环打印了

有序打印

回到打印这一块,可以看到除了无序的HashMap,不是还有TreeMap

TreeMap具有有序性,就可以有序打印。

HashMap的规则等等,到后面再深入,这里只要知道了解即可

可以再看一下TreeMapHashMapput就能直接证明

TreeMapComparator比较,HashMap没有

总结

这篇文章只是初识,简单先把其中的内容都罗列出来

后面要学习的东西,可是相当的爽,爽爆!

小头图版权:《⸜♥⸝》by 桜ひより◆2日目西ひ44b 2021年12月7日晚上11点30分 pid:94635920

广告位招租
最后修改:2021 年 12 月 09 日 08 : 15 PM
如果觉得我的文章对你有用,请喂饱我!(理直气壮)