• java中的集合框架基础-2


    一.泛型的基础编程
            类型的在编写代码时不确定---引入类型参数
            在类上使用泛型
            泛型个数没有约束,一般使用全大写的单个字母表示,不同泛型使用逗号分割

     泛型类的用法
            class 类型名称<泛型名称>{   形参
                泛型名称  属性名称;
              public 泛型名称 pp1(){}
              public 泛型名称 pp2(泛型名称 bb){}
              public void pp3(泛型名称 bb1, 其他类型参数){}
      }

      注意:不能在静态方法中使用泛型
             public static void bb(T id){}语法报错
             正确的写法为public static void bb(T id){}
             使用静态方法的泛型时和类上的泛型无关
     泛型方法的用法
     泛型实例方法
           public int pp1(TA num){}
     泛型静态方法
            public static TB pp2(TB bb){}
     泛型上限 extends
                 泛型上限中所使用的类只能有一个,接口无数多个
             public class A {} 
    通配符 ?
     ``上限通配符,用来限制类型的上限
            public void pp(List list){}//表示list中元素的类型必须是
    T类型或者T类型的子类或者T接口的实现类
     ``下限通配符,用来限制类型的下限
             public void pp(List list){}//表示list中元素的类型必须是T类
     型或者T类父类或者T接口的实现类或者T的父接口实现类

    二.两个特殊的数据结构
       栈Stack:FILO
                定义栈
                  对栈的基本操作只有push进栈和pop出栈两种,栈的实现可以有数组实现的顺序栈和链表结构的链式栈
            java提供的具体实现类Stack
                public class Stack extends Vector 
                    E push(E item)  将数据存储到数组中,如果集合已经满了,则添加新数据时增容
                    E pop() 弹出栈顶数据
                    E peek() 查看栈顶数据,并不会执行弹出操作
                 search(Object o) 查找o对象的下标值
              1、定义接口

    1. public interface Stack {
    2. //栈是否为空 记得在方法上添加注释
    3. boolean isEmpty();
    4. // data元素入栈
    5. void push(T data);
    6. //返回栈顶元素,未出栈
    7. T peek();
    8. //出栈,返回栈顶元素,同时从栈中移除该元素
    9. T pop();
    10. }


               2、实现类,这里忽略了抽象类
                //顺序栈

    1. public class SeqStack implements Stack {
    2. // 栈顶指针,-1代表空栈
    3. private int top = -1;
    4. // 容量大小默认为10
    5. private static final int capacity = 10;
    6. // 存放元素的数组
    7. private T[] array;
    8. //当前栈中存储的元素个数
    9. private int size;
    10. public SeqStack() {
    11. this(capacity);
    12. }
    13. @SuppressWarnings("unchecked")
    14. public SeqStack(int capacity) {
    15. array = (T[]) new Object[capacity];
    16. }
    17. public int size() {
    18. return size;
    19. }
    20. public boolean isEmpty() {
    21. return this.top == -1;
    22. }
    23. // 添加元素,从栈顶(数组尾部)插入
    24. public void push(T data) {
    25. // 判断容量是否充足
    26. if (array.length == size)
    27. ensureCapacity(size * 2 + 1);// 扩容
    28. // 从栈顶添加元素
    29. array[++top] = data;
    30. size++;
    31. }
    32. private void ensureCapacity(int capacity) {
    33. // 如果需要拓展的容量比现在数组的容量还小,则无需扩容
    34. if (capacity < size)
    35. return;
    36. T[] old = array;
    37. array = (T[]) new Object[capacity];
    38. System.arraycopy(old, 0, array, 0, size);
    39. }


                    // 获取栈顶元素的值,不删除
              

    1. public T peek() {
    2. if (isEmpty())
    3. throw new EmptyStackException();
    4. return array[top];
    5. }

       // 从栈顶(顺序表尾部)删除

    1. public T pop() {
    2. if (isEmpty())
    3. throw new EmptyStackException();
    4. size--;
    5. return array[top--];
    6. }
    7. }

        队列Queue:FIFO
            根据实现方式不同分为顺序队列和链式队列。
                enqueue(String item) 入队操作
                dequeue() 出队操作
               
                循环队列:基于数组的队列实现中,当tail=items.length时需要搬移大量的数据,就会导致
                入队操作的性能降低,可以使用循环队列解决
                
                典型算法:约瑟夫环
         
                队列接口 Queue

    1. public interface Queue extends Collection {
    2. boolean add(E e);向队列中添加数据,阈值为64,Double size if small; else grow by 50%
    3. boolean offer(E e);
    4. E remove(); 删除队列头部的数据
    5. E poll();
    6. E element();获取队列中的数据
    7. E peek();
    8. }

            Deque 双向队列
                ### 优先队列
                
                PriorityQueue是AbstractQueue的实现类,优先级队列的元素根据自然排序或者在构造函数时期提供
                Comparator来排序,具体根据构造器判断。PriorityQueue不允许null元素
                
                - 队列的头在某种意义上是指定顺序的最后一个元素。队列查找操作poll、remove、peek和element访
                问队列头部元素
                
                - 优先级队列是无限制的,但是具有内部capacity,用于控制在队列中存储元素的数组大小
                
            - 该类以及迭代器实现了Collection、Iterator接口的所有可选方法,这个迭代器提供了iterator()方法不能保证以任何特定顺序遍历优先级队列的元素。

    如果需要有序遍历使Arrays.sort(queue.toArray())
            
            - 注意这个实现不是线程安全的,多线程不应该并发访问PriorityQueue实例,如果有某个线程修改了队列的话,使用线程安全的类PriorityBlockingQueue
            
            PriorityQueue是优先队列,作用是保证每次取出的元素都是队列中权值最小的,这里涉及到了大小关系,元素大小的评判可以通过元素自身的自然顺序(使用默认的比较器),也可以通过构造时传入的比较器。
            Java中PriorityQueue实现了Queue接口,不允许放入null元素;其通过堆实现,具体说是通过完全二叉树complete 
            binary tree)实现的小顶堆(任意一个非叶子节点的权值,都不大于其左右子节点的权值),也就意味着可以
            通过数组来作为PriorityQueue的底层实现。
            
    阻塞队列就是在队列的基础上添加了阻塞特性。在队列为空时,从队头获取数据会被阻塞,直到队列中有数据才返回;在队列已满时,插入数据的操作会被阻塞,直到队列中空闲位置后才插入数据,然后返回。基于阻塞队列的生产者-消费者模式可以有效地协调生产和消费的速度。

    #### BlockingQueue接口

    方法    抛出异常    返回特殊值    一直阻塞    超时退出
    插入    add(e)    offer(e)    put(e)    offer(e, tiime, unit)
    移除    remove()    poll()    take()    poll(tiime, unit)
    查看    element()    peek()

    java针对阻塞队列提供了7种常见的实现,分别是
        ArrayBlockingQueue由数组结构组成的有界阻塞队列、
        LinkedBlockingQueue由链表结构组成的有界阻塞队列,默认长度为Integer.MAX_VALUE,如果指定长度则有上限、
        PriorityBlockingQueue支持优先级排序的无界阻塞队列、
        DelayQueue使用优先级队列实现的无界阻塞队列、
        SynchronousQueue不存储元素的阻塞队列,只起到一个同步器的作用、
        LinkedTransferQueue由链表结构组成的无界阻塞队列、
        LinkedBlockingDeque由链表结构组成的双向阻塞队列。

  • 相关阅读:
    mysql面试题4:MySQL中什么是聚集索引、非聚集索引?什么是MySQL主键索引、唯一索引、全文索引?
    股票交易接口使用步骤
    什么是鉴权?这些postman鉴权方式你又知道多少?
    学Python,还不知道main函数吗
    神经辐射场(NeRF)2023最新论文及源代码合集
    黑猫带你学Makefile第13篇:Makefile编译问题合集
    Linux C程序编译链接的过程,gcc/g++,动态库/静态库
    《LKD3粗读笔记》(11)定时器和时间管理
    华为又“捅破天”发布新品Mate60 Pro直连天通一号卫星通话,北斗卫星通信飞入寻常百姓家
    【MySQL】MySQL中的逻辑运算符,位运算符和运算符的优先级
  • 原文地址:https://blog.csdn.net/m0_56627229/article/details/126591209