【数据结构】集合框架及背后的数据结构【详解篇1】

【前言】Java语法的系列学习已经结束了,现在开始数据结构集合类的学习,这里学习的数据结构是基于Java的数据结构,下图是本次数据结构的学习内容大纲,仅供参考。有计划,有目标,才有方向;不放弃,不懈怠,才有结果。

image-20211009160116357


【提示】:主要还是看代码示例:细节知识点都是都藏在代码注释里呢。

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

数据结构:是组织数据的一种方式。

集合及其背后的数据结构:在java当中,Java把很多的数据结构全部都封装起来了,封装成一个一个的现成的类。只需要拿过来使用就行了,但是在使用的时候需要知道其底层原理。这个底层原理就是我们所说的数据结构。集合类就是把这些数据结构已经封装成一个一个独有的类了,可以拿过来直接使用。

简单介绍

官方教程
Java 集合框架 (Java Collection Framework) ,又被称为容器 container ,是定义在 java.util 包下的一组接口 (interfaces )和其实现类( classes) 。其主要表现为将多个元素 (element) 置于一个单元中,用于对这些元素进行快速、便捷的存储 (store)、检索(retrieve)、管理( manipulate) ,即平时我们俗称的增删查改 (CRUD )。

例如,一副扑克牌(一组牌的集合)、一个邮箱(一组邮件的集合)、一个通讯录(一组姓名和电话的映射关系)等。

类和接口总览
image-20210929105304832

image-20210929112544292

对上图的文字分析叙述:

  • Iterable接口:顶层接口 Iterable(可迭代的),它用于遍历。
  • 迭代:通过若干个有限的步骤,逐步逼近最终结果。在集合类里面它所代表的具体含义就是:能够进行从前到后的遍历,取出每个元素。

接下来所介绍的集合类,只要实现了Iterable接口,就可以进行这样的遍历过程。

  • Collection接口:它是一个集合,收集很多元素放在一起。它不仅可以遍历和可以进行增删改查操作。它的表示形式有以下三种:他们三个实现了Collection接口

    • List接口:它表示一个列表,它里面的元素是相对有序的,可以中间位置插入删除。它的表示形式有以下三种,它们三个实现了List接口

      • Vector类:它也是一个顺序表,只不过是旧版本的顺序表,现在很少用了。
    • ArrayList类:顺序表的实现

    • LinkedList类:链表的实现

    • Stack类:它是一个栈(后进先出)

    • Queue接口:队列(先进先出),它里面的元素也是相对有序的,只能头插/头删,尾插/尾删。

      • Deque接口:双向队列(既可以从头进从头出,也可以从尾进从尾出),他还有一个具体的类LinkedList
      • LinkedList类:LinkedList也实现了Queue接口
      • PriorityQueue:优先队列,它是一种特殊的队列,里面的元素是具有优先级的,他不是简单的先进先出,而是按照优先级的高低决定谁先出谁后出,它底层的数据结构是对应到堆上的
    • Set接口:Set和List、Queue有一定的区别,List接口里面要求元素之间相对取得有序的,Queue接口里面要求的不光是有序还更加限制了操作接口,而Set里面不要求元素有序(即:认为1,2,3和3,2,1是相同的)。

      • SotredSet接口:
      • Set接口具体的实现一个是TreeSet类(基于二叉搜索树的实现);
      • 一个是HashSet类(基于哈希表的实现)。

Map接口:它里面存储的是”键值对“,它有两种具体的实现。

  • HashMap:基于哈希表的实现(重中之重),哈希这种思想方法是当前互联网分布式系统的理论基础。
  • TreeSet:基于二叉搜索树的实现

从上面这个图中要知道两个东西,一个是他们之间关系,另一个是他们背后的数据结构。

  • 关系

接口和接口之间的关系:一个接口可能有一个功能,它要拓展另外一个接口,就需要extends(继承)这个接口,所以接口和接口之间是extends(继承)的关系。

类和接口的关系:是实现implements。

  • 背后的数据结构:如类和接口总览

image-20210929105202464

Java 集合框架的优点及作用

  • 使用成熟的集合框架,有助于我们便捷、快速的写出高效、稳定的代码
  • 学习背后的数据结构知识,有助于我们理解各个集合的优缺点及使用场景
为什么会有这么多的数据及结构?

因为组织数据的方式不一样,所以才有这么多的数据结构来提供使用,既然有这么多的数据结构,那么必然每一种数据结构都有自己使用的场景以及它的优缺点。

笔试及面试题

集合在面试和笔试的时候占有非常大的比例,所以要十分注意!

腾讯-Java后台开发面经

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

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

  1. ArrayList 和 LinkedList 的区别是什么?(即顺序表和链表的区别或数组和链表的区别)
  2. 有了解过 HashMap 的具体实现么?
  3. HashMap 和 ConcurrentHashMap 哪个效率更高?

今日头条-Java后台开发面经

  1. 编程题:判断一个链表是否是一个回文链表。
  2. Redis 的 zset 类型对应到 java 语言中大致是什么类型?
  3. hashCode 主要是用来做什么用的?

接口interfaces

基本关系说明

image-20210929112053639

1、Collection :用来存储管理一组对象 (objects) ,这些对象一般被成为元素( elements)

List : 线性结构

​ Queue : 队列

​ Set : 元素不能重复,背后隐含着查找/搜索的语义

​ Deque : 双端队列

​ SortedSet : 一组有序的不能重复的元素

2、Map : 键值对 Key-Value-Pair ,背后隐含着查找****/搜索的语义

SortedMap : 一组有序的键值对

Collection 接口说明

Collection官方文档

打开帮助手册我们就能看到更多更详细的关于Collection的方法

image-20210930232526224

Collection常用方法说明
方法签名说明
boolean add(E e)将元素e放入集合中
void clear()删除集合中的所有元素
boolean isEmpty()判断集合是否没有任何元素,俗称空集合
boolean remove(object e)如果元素e出现在集合中,删除其中一个
int size()返回集合中的元素个数
object[] toArray()返回一个装有所有集合中元素的数组
  • E:代表的就是Collection 这里指定的字符串类型
  • Collection的核心操作是增删改查。

代码示例:Collection常用方法的使用

public class TestDemo1 {
    public static void main(String[] args) {
      /**
        *注意:
        * (1)、Collection 需要导包
        * (2)、Collection是一个接口,定义引用的时候不能new Collection ,应该new一个来自于Collection 的具体的类
        * ,如:new ArrayList()、new LinkedList()等,他们都实现了Collection 接口,也可以发生向上转型。
        * (3)、根据ArrayList()来举例,学习各个方法的使用*/
        //《1、创建Collection》
        Collection<String> collection1=new ArrayList<>();//这个意思表示collection1它所引用的是一个顺序表
      //这个顺序表里面只能放String(字符串)
      //Collection collection=new LinkedList();
      //《2、使用add方法:将元素e放入集合中》
        collection1.add("hehe");//add中的参数类型必须和泛型参数类型匹配
        collection1.add("学习Java");
      /*collection1.add(2);error:这样写就错了,因为Collection已经指定放一个字符串,所以不能放整型,必须放字符串。
        如果想要放整型,就需要让Collection指定Integer包装类(如下),即需要放什么就指定什么
        Collection<Integer> collection2=new ArrayList<>();*/
        System.out.println("将元素e放入集合中:"+collection1);//打印集合里的东西
      //《3、使用clear方法:删除集合中的所有元素》
        collection1.clear();//因为ArrayList实现了collection接口,所以调用clear的时候,调用的不是collection中的clear,而是ArrayList重写clear这个方法
        System.out.println("删除集合中的所有元素:"+collection1);
      //《4、使用isEmpty方法:判断集合是否没有任何元素,俗称空集合》
        System.out.println("判断集合是否没有任何元素:"+collection1.isEmpty());
      //《5、使用remove方法:如果元素e出现在集合中,删除其中一个》
        Collection<String> collection2=new ArrayList<>();
        collection2.add("哈哈");
        collection2.add("好好学习Java");
        System.out.println("没删除元素之前:"+collection2);
        collection2.remove("哈哈");
        System.out.println("删除其中一个元素之后:"+collection2);
      //《6、使用size方法:返回集合中的元素个数》
        System.out.println("collection1的长度:"+collection1.size());
        System.out.println("collection2的长度:"+collection2.size());
      //《7、使用toArray方法:返回一个装有所有集合中元素的数组》
        Collection<String> collection3=new ArrayList<>();
        collection3.add("计算机工程学院");
        collection3.add("计算机科学与技术");
        collection3.add("班级:计本1801班");
        collection3.add("学号:001");
        collection3.add("备注");
        System.out.println(collection3);
        collection3.remove("计算机科学与技术");
        System.out.println("删除其中一个元素之后:"+collection3);
     //通过collection3去调用toArray就会把collection3里面所有的东西变成一个数组,toArray的返回值为Object[]类型的,一个数组,所以定义一个变量,接收一下,然后将这个数组打印出来。
        Object[] objects=collection3.toArray();
        System.out.println(Arrays.toString(objects));
            }
        }

打印结果:image-20211001003129845

也可使用for each打印,代码示例如下:

 public static void main(String[] args) {
        Collection<String> collection1=new LinkedList<>();
        collection1.add("123");
        collection1.add("小红");
        collection1.add("小明");
        //也可使用for each 进行打印,来遍历集合中的元素
        //一般能用for each的就是它继承了Iterable接口
        for (String s:collection1) {//s 就会分别指向collection中的每一个元素
            System.out.println(s);
        }
        collection1.clear();
        System.out.println(collection1);
 }
//打印结果:
123
小红
小明
[]

代码句析1:image-20211002131121999

注意事项1:length和size的区别和使用格式

  • 获取数组元素个数:使用.length 不带括号的
  • 获取字符串字符个数:使用.length() 带括号的
  • 获取集合元素个数:使用.size()
Map常用方法说明

Map官方文档

方法签名说明
V get(Object k)根据指定的K查找对应的V
V getOrDefault(Object k, V defaultValue)根据指定的 k 查找对应的 v,没有找到用默认值代替
V put(K key, V value)将指定的k-v放入map
boolean containkey(Object key)判断是否包含key值
boolean containsValue(object value)判断是否包含 value
Set<Map.Entry<k,v>> entrySet()将所有键值对返回
boolean isEmpty()判断是否为空
int size()返回键值对的数量
  • Map是键值对<key,value>的形式写的,通过key来找到对应的value
  • key可能是一个字符串,value也可能是一个字符串;
  • 同Collection一样,Map是一个接口,定义引用的时候不能new Map ,应该new一个来自于Map 的具体的类
  • new实体类,可以new HashMap或者TreeMap.
  • Map的核心操作是增删改查以及get和put

代码示例:Map 常用方法的使用

 public static void main(String[] args) {
     //《1、创建Map实例》:它的泛型参数有两个,一个参数是key的类型,第二个参数是value的类型
        Map<String,String> map=new HashMap<>();//哈希表
        //2、put方法:《将指定的 k-v 放入 Map》
        /*注意1:key值如果重复,value值必然是最新的那个
          注意2:哈希表在打印数据的时候,打印的顺序不一定就是存储的顺序
          注意3:key值尽量不要重复,value值可以重复*/
        map.put("主持人","撒贝宁");
        map.put("歌手","薛之谦");
        map.put("演员","任嘉伦");
        map.put("作家","鲁迅");
        map.put("作品","《狂人日记》");
        map.put("作品","《呐喊》");//key值如果重复,value值必然是最新的那个
        System.out.println(map);//打印map里面的所有元素
        //3、get方法:《根据指定的K查找对应的V》
        String s= map.get("歌手");//get方法的返回值是一个V,对应Map里面的<K,V>,因为这里V是String,所以get的返回值就是String类型
        //所以就可以通过String来接收,并打印
        System.out.println(s);//歌手对应的value值是薛之谦
        String s1=map.get("歌手1");//找歌手1所对应的value值,如果找不到则返回为null
        System.out.println(s1);
        //4、getOrDefault方法:《根据指定的 k 查找对应的 v,没有找到用默认值代替》
        String s2= map.getOrDefault("歌手1","许嵩");//找歌手1所对应的value值,如果找不到默认值就给一个许嵩
        System.out.println(s2); 
        //5、containsKey方法:《是否包含key值》
        System.out.println(map.containsKey("作家"));//返回值是boolean类型
        //6、containsValue方法:《判断是否包含 value》
        System.out.println(map.containsValue("许嵩"));
     //containsKey的执行效率比、containsValue的执行效率高,所以更推荐使用containsKey
        //7、entrySet()方法:《将所有键值对返回》
        Set<Map.Entry<String,String>> set=map.entrySet();//entrySet()方法的返回值是Set
     //Entry:表示一个“条目”,也就是一个键值对
     //map.entrySet():表示获取到所有的键值对

        System.out.println(set);//将集合当中的元素打印出来
        for (Map.Entry<String,String> entry:set) {//也可使用for each方式打印,打印出一个一个集合
           /* entry.getKey();//拿到key值
            entry.getValue();//拿到value值*/
            System.out.println(entry.getKey()+"=="+entry.getValue());
        }
        //8、isEmpty方法《判断是否为空》
        System.out.println(map.isEmpty());
        //9、《返回键值对的数量》使用size获取到元素的个数,这里的个数指的是键值对的个数
        System.out.println(map.size());
    }

打印结果:

image-20211001183952769
  • 对Set<Map.Entry<K,V>> entrySet(),这个方法的解释:
    image-20211001184050273
实现Classes

这张图中表示的是每一个接口是由哪些类进行实现的。

interface顺序表链表红黑树哈希表
SetTreeSetHashSet
ListArrayListLinkedList
QueueLinkedListPriorityQueue
DequeLinkedList
MapTreeMapHashMap

除此之外,还会学习java中的栈stack。

注意重点内容

  • Java 集合框架中接口、之间的关系及其含义。
  • Java 集合框架中接口和其各自对应的常见实现类之间的关系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值