【JavaSE】十一、Stack && Queue && Deque && PriorityQueue && Map && Set

文章目录

  • [Ⅰ. Stack(不推荐使用了☠)](#Ⅰ. Stack(不推荐使用了☠))
  • [Ⅱ. Queue](#Ⅱ. Queue)
  • [Ⅲ. Deque](#Ⅲ. Deque)
  • [Ⅳ. PriorityQueue](#Ⅳ. PriorityQueue)
  • [Ⅴ. Map](#Ⅴ. Map)
  • [Ⅵ. Set](#Ⅵ. Set)

Ⅰ. Stack(不推荐使用了☠)

常见方法如下所示:

其中 peek() 就相当于是 std::stack 中的 top()

注意事项:

  1. 在比较元素相同的时候,要使用 equals(),因为就算存储的是整数 Stack<Integer> 类型,里面仍然是引用类型,不能直接通过 == 来比较

  2. 因为 Stack 继承于 Vector,而 Vector 中还有很多实用的方法比如 size() 方法等,都是可以使用的,但由于 Vector 比较老,并且这种设计违反了最小接口原则 ,所以现在不推荐使用 Stack,而是 Deque 来替代!(如下面代码所示)

    1. Java 推荐使用 Deque 接口的实现类,比如:

      1. ArrayDeque
      2. LinkedList
      java 复制代码
         Deque<Integer> stack = new ArrayDeque<>(); // 使用Deque代替Stack
         
         stack.push(1);    // 入栈
         stack.pop();      // 出栈
         stack.peek();     // 查看栈顶
         stack.isEmpty();  // 是否为空

Ⅱ. Queue

注意事项:

  • Queue 是一个接口,要使用实现类来实现,常用 LinkedListArrayDequePriorityQueue 来实现!
  • 一个队列可以实现 栈,但是一个栈实现不了 队列!225. 用队列实现栈232. 用栈实现队列

Ⅲ. Deque

Deque 是一个接口,使用时必须创建 LinkedList 或者 ArrayDeque 类型的对象 。在实际工程中,使用 Deque 接口是比较多的,栈和队列均可以使用该接口。

java 复制代码
Deque<Integer> stack = new ArrayDeque<>(); // 双端队列的线性实现 
Deque<Integer> queue = new LinkedList<>(); // 双端队列的链式实现
操作类型 方法名 描述 抛出异常版本 返回特殊值版本
插入 addFirst(e) 在队首插入元素 如果容量受限会抛出IllegalStateException offerFirst(e) - 失败返回false
addLast(e) 在队尾插入元素 同上 offerLast(e) - 失败返回false
移除 removeFirst() 移除并返回队首元素 队列为空时抛出NoSuchElementException pollFirst() - 队列为空返回null
removeLast() 移除并返回队尾元素 同上 pollLast() - 队列为空返回null
查看 getFirst() 查看队首元素(不移除) 队列为空时抛出NoSuchElementException peekFirst() - 队列为空返回null
getLast() 查看队尾元素(不移除) 同上 peekLast() - 队列为空返回null
栈操作 push(e) 将元素压入栈 可能抛出IllegalStateException
pop() 弹出栈顶元素 栈为空时抛出NoSuchElementException
其他 size() 返回队列中元素数量 - -
isEmpty() 判断队列是否为空 - -
contains(o) 判断是否包含指定元素 - -
remove(o) 移除第一个匹配的元素 元素不存在时抛出NoSuchElementException

Ⅳ. PriorityQueue

Java 集合框架中提供了 PriorityQueuePriorityBlockingQueue 两种类型的优先级队列,PriorityQueue 是线程不安全的,PriorityBlockingQueue 是线程安全的,下面主要介绍 PriorityQueue

使用注意事项:

  1. 使用时必须导入包:import java.util.PriorityQueue;
  2. PriorityQueue放置的元素必须要能够比较大小 ,不能插入无法比较大小的对象,否则会抛出 ClassCastException 异常。
  3. 不能插入 null 对象 ,否则会抛出 NullPointerException
  4. PriorityQueue 默认情况下是小堆
  5. 创建自定义大小堆的比较器写法如下所示:(以 Integer 为例)
java 复制代码
// 推荐使用 Comparator 而不是 Comparable,因为前者比较灵活、侵入性小
// 创建小堆
class lesscmp implements Comparator<Integer> {
    @Override
    public int compare(Integer o1, Integer o2) {
        return o1.compareTo(o2);
    }
}

// 创建大堆
class greatercmp implements Comparator<Integer> {
    @Override
    public int compare(Integer o1, Integer o2) {
        return o2.compareTo(o1);
    }
}

public static void main(String[] args) {
    PriorityQueue<Integer> pq = new PriorityQueue<>(); // 默认为小堆
    pq.add(10);
    pq.add(20);
    pq.add(15);
    while(!pq.isEmpty()) {
        System.out.println(pq.poll());
    };

    PriorityQueue<Integer> pq1 = new PriorityQueue<>(new greatercmp());
    pq1.add(10);
    pq1.add(20);
    pq1.add(15);
    while(!pq1.isEmpty()) {
        System.out.println(pq1.poll());
    }
    
    // 使用lambda表达式创建大堆
    PriorityQueue<Integer> pq2 = new PriorityQueue<>((o1, o2) -> {return o1.compareTo(o2)});
    pq2.add(10);
    pq2.add(20);
    pq2.add(15);
    while(!pq2.isEmpty()) {
        System.out.println(pq2.poll());
    }
}

// 运行结果
10
15
20

20
15
10

20
15
10

堆排序

  • 升序:建大堆
  • 降序:建小堆
  • 时间复杂度:O(nlogn)

Ⅴ. Map

Map 是一个接口类 ,该类没有继承自 Collection,该类中存储的是 <K,V> 结构的键值对,并且 K 一定是唯一的,不能重复

https://docs.oracle.com/javase/8/docs/api/index.html

☠注意事项

  1. 内置类型不能直接来实例化 HashMap,必须要找其对应的包装类型
  2. TreeMap 中的 key 不能为空 ,否则就会抛 NullPointerException 异常,value 可以为空;而 HashMap key value 都可以为空
  3. Map 中键值对的 Key 不能直接修改,value 可以修改,如果要修改 key,只能先将该 key 删除掉,然后再来进行重新插入。
  4. HashMap 的底层实现中,当某个桶中链表元素超过 8 个,并且桶的个数超过 64 个,此时会将该桶中的链表转化为红黑树维护,降低高度!
  5. 采用方法如下所示:
  1. 其中 getOrDefalut() 方法通常用于统计次数的时候简化代码,如下所示:

    java 复制代码
    public List<String> topKFrequent(String[] words, int k) {
        // 统计字符串出现个数
        Map<String, Integer> hash = new HashMap<>();
        for(int i = 0; i < words.length; ++i) {
            hash.put(words[i], hash.getOrDefault(words[i], 0) + 1); // 这样子来简化代码
        } 
        ...
    }
  2. Map (如 HashMapTreeMap 等) 自身没有迭代器 ,即没有实现 Iterator 接口,但它的视图对象(keySetentrySetvalues)都可以迭代,如下所示:

    java 复制代码
    // 遍历 keySet()(只要 key)
    for (K key : map.keySet()) {
        System.out.println(key);
    }
    
    // 遍历 values()(只要 value)
    for (V value : map.values()) {
        System.out.println(value);
    }
    
    // 遍历 entrySet()(需要 key 和 value)⭐⭐⭐⭐⭐⭐⭐(推荐)
    for (Map.Entry<K, V> entry : map.entrySet()) {
        System.out.println(entry.getKey() + " = " + entry.getValue());
    }
  3. 上述的 entrySet()Map 接口中的一个方法,返回一个包含了所有 键值对 的 Set 集合 ,这些键值对就是 Map.Entry<K, V> 对象,它们每一个都包含两个元素:keyvalue

    java 复制代码
    // 也就是说上面的for-each可以转化为迭代器来处理,如下所示:(这里只举例entrySet)
    Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator();
    while(it.hasNext()) {
        System.out.println(it.next().getKey() + " " + it.next().getValue());
    }
  4. TreeMapHashMap 的区别如下图所示。其中因为 HashMap 在比较内容的时候是根据 hashCode() 来确定 key 是在哪个桶中的,而根据 equals() 来确定是桶中的哪个元素,所以 HashMap 中存放自定义类型的时候,需要重写该自定义类型的 equals() hashCode() 方法

Ⅵ. Set

SetMap 主要的区别:

  1. Set 是继承自 Collection 的接口类
  2. Set 中只存储了 Key

但实际上底层源码实现是让 Set 去调用 Map 的接口 ,只不过传入的 value 是一个默认的 Object 对象,而只需要关心 key 即可。

常用方法如下所示:

注意事项:

  1. Set 最大的功能就是对集合中的元素进行去重
  2. 实现 Set 接口的常用类有 TreeSetHashSet,还有一个 LinkedHashSetLinkedHashSet 是在 HashSet 的基础上维护了一个双向链表来记录元素的插入次序
  3. TreeSet 中不能插入 nullkey,而 HashSet 可以。
相关推荐
油丶酸萝卜别吃2 小时前
springboot项目中与接口文档有关的注解
java·spring boot·后端
fufu03112 小时前
Linux环境下的C语言编程(三十九)
c语言·数据结构·算法·链表
小码哥0682 小时前
家政服务管理-家政服务管理平台-家政服务管理平台源码-家政服务管理平台java代码-基于springboot的家政服务管理平台
java·开发语言·spring boot·家政服务·家政服务平台·家政服务系统·家政服务管理平台源码
前端小L2 小时前
回溯算法专题(十):二维递归的完全体——暴力破解「解数独」
数据结构·算法
Java爱好狂.2 小时前
复杂知识简单学!Springboot加载配置文件源码分析
java·spring boot·后端·spring·java面试·后端开发·java程序员
Array*2 小时前
java实现word中插入附件(支持所有文件格式)
java·开发语言·word·poi·ole
Donald_brian2 小时前
线程同步
java·开发语言·jvm
全靠bug跑2 小时前
Nacos 入门实战:部署、服务注册与发现全指南
java·spring cloud·docker·nacos
郑州光合科技余经理2 小时前
技术视角:海外版一站式同城生活服务平台源码解析
java·开发语言·uni-app·php·排序算法·objective-c·生活