【Java之栈和队列】

栈和队列

**线性表:**连续的,每个元素都有唯一的前驱和后继

数组和链表

数组

地址是连续的

随机访问公式:数组起始地址 + 下标 * 数组单个存储单元的大小

链表

形象地说,链表就是用一串链子将结点串联起来。

结点:包含数据域和指针域。
数据域:数据
指针域:下一个结点的地址

单链表: 除了尾结点, 每一个结点都有一个后继结点

循环链表: 尾结点的下一个结点指向头结点

双线链表: 有后继结点还有前驱结点

双向循环链表: 尾结点的下一个指向头, 头结点之前指向尾结点

常用的是双链表

取中间值和判断链表是否有环的常用方法:快慢指针

反转链表:头插法

泛型

泛型: 参数化类型 ()
事先不指定数据类型,等到使用的时候再确定

泛型的好处
a. 提高了程序的安全性
b. 将运行期遇到的问题转移到了编译期
c. 省去了类型强转的麻烦

泛型的使用

泛型类
// 把泛型定义到类上, 就是泛型类

泛型类: 把泛型定义在类上
格式:class 类名 <泛型类型1,>
注意:参数化类型必须是引用类型
    
// 注意2: 如果某一个代码中我们使用的时候应该传入泛型, 但是我们没有传, 那么它默认是Object类型
		 User user = new User("zs", 18);
        Object age2 = user.getAge();

// 注意3: 注意一些泛型定义的习惯问题
        // 给泛型定义的时候: 习惯上
        // T: type
        // E: element
        // K: key
        // V: value

// 注意4: 不要给一个类定义超过两个泛型(不是语法不允许),  习惯上显得怪异

// 注意5: 在泛型类上定义的泛型, 作用域, 仅仅局限于类名和类体内

泛型的通配

泛型通配符:

① 泛型通配符<?>
任意类型,如果没有明确,那么就是Object以及任意的Java类了
② ? extends E
向下限定,E及其子类
③ ? super E
向上限定,E及其父类

     ArrayList<?> list = new ArrayList<Character>();
        // 报错的原因: 因为从编译角度, 仅能推断出?代指一个不确定的类型
        //        从java语法角度, 一个不确定的类型, 没有存储其它类型(String存储Integer肯定无法运行)
        // 为了避免运行时出现问题, 直接不让添加
        // list.add("zs");// 报错:
        // list.add(new Object());// 报错

ArrayList<? extends F> list = new ArrayList<S2>();
        // 报错的原因: 因为从编译角度, 仅能推断出? extends F代指一个不确定的f或者f的子类型
        //        从java语法角度, 一个不确定的类型, 没有存储其它类型
        // 为了避免运行时出现问题, 直接不让添加
        //list.add("zs");//报错
        //list.add(new Object());//报错
        //list.add(new F());//报错
        //list.add(new S1());//报错

        ArrayList<? super F> list = new ArrayList<F>();
        // list.add("zs");//报错
        // list.add(new Object());//报错
        list.add(new F());
        list.add(new S1());
        list.add(new S2());

class F {}
class S1 extends F{}
class S2 extends F{}

泛型擦除

java中的泛型并不是真正的泛型, java中的泛型只存在于代码编译之前, 代码编译的时候, 这些泛型的写法统统会被擦除, 变成Object以及类型强转.

FILO

链表实现栈时运用头插法

栈的应用

应用场景:

  1. 函数调用栈
  2. 反序字符串
    实现reNumber(str)方法,反转字符串
  3. 括号匹配问题
    实现judgeBracket(str)方法来判断括号匹配
  4. 编译器利用栈实现表达式求值
  5. 浏览器的前进后退功能
  6. 利用栈实现 DFS: depth-first-search 深度优先遍历
  7. 波兰表达式

队列

FIFO

用链表实现队列时,头节点作为队列头实现出队列,尾节点作为队列尾实现入队列

普通队列的应用场景是很有限的,一般在工程中用到的是阻塞队列。
阻塞队列:常用于生产者-消费者模型中。

队列大小固定:
当队列满的时候,入队列就阻塞。
当队列空的时候,出队列就阻塞。

队列应用场景:
缓存

你可能感兴趣的:(#,Java核心技术精选,java,开发语言)