• 数据结构前瞻


    集合框架

    JAVA的集合框架是定义在java.util包下的一组接口和实现类,用于将多个元素置于一个单元中,对这些元素进行快速,便捷的存储,减速和管理,即增删查改

    下面的格子,黄色代表接口,蓝色代表抽象类,棕色代表类

     是动态数组(顺序表)优先级队列

    是双向列表 底层就是一颗红黑树

    重要的四个接口


    算法效率

    时间复杂度

    即算法中基本操作的执行次数

    比如这张图,因为for循环执行了两次,每次都有n个目标的执行

    F(N) = N^2 + 2N + 10

    大O渐进表示法

    1.用常数1取代运行时间中的所有加法常数

    2.修改后的运行次数函数中,只保留最高阶项。

    3.如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶

    最坏情况:任意输入规模的最大运行次数 ( 上界 )
    平均情况:任意输入规模的期望运行次数
    最好情况:任意输入规模的最小运行次数 ( 下界 )

     

    F(N) = 2 * N + 10

    O(N) = N

    最好情况下:比较一次发现sorted是true直接退出循环,此时时间复杂度是O(N)(因为要对N个数据对N次遍历)

    最坏情况下:n-1+n-2+n-3+......+2+1

    等差数列计算公式(1+n-1)*(n-1)/2 = (n^2-n)/2 -->  O(n^2)

    这里不能单纯只看到一个循环就说O(N),我们要从代码思想上分析

    最坏情况:二分到最后一个才被找到

    n/2^x = 1 (x表示次数)

    n = 2^x -- >  x = logn(二进制中下底2省略)--> O(logn)

    递归

    递归的时间复杂度 = 递归的次数*每次递归后执行的次数

    因为这里是三目运算,所以递归执行次数为1,那递归的次数就看factorial(N-1),就是O(N-1)

    算到F(1) = 2^n + 2^(n-1)+ ...+ 2+ 1

    1*(1-2^n)/1-2 = 2^n -1 --> O(2^n)


    空间复杂度

    临时占用存储空间大小的量度

    int[] array是一个数组,也就是一个对象,占用一块空间,也就是O(1)

    求第n个斐波那契数字?需要开辟n块空间存储n个数字。O(n)

    O(n)


    包装类

    基本数据类型   包装类
    byte                  Byte
    short                Short
    int                    Integer
    long                  Long
    float                  Float
    double             Double
    char                Character  
    boolean           Boolean

    1. public static void main1(String[] args) {
    2. Integer a = 10;//装包 自动装箱
    3. int i = 99;
    4. Integer b = i;
    5. //基本类型 给转变为 包装类型
    6. System.out.println(a);//10
    7. System.out.println(b);//99
    8. Integer aa = Integer.valueOf(10);//显示装箱
    9. }

     valueOf底层

    1. public static Integer valueOf(int i) {
    2. if (i >= IntegerCache.low && i <= IntegerCache.high)
    3. return IntegerCache.cache[i + (-IntegerCache.low)];//装箱
    4. return new Integer(i);
    5. }


    拆包,拆箱 

    1. Integer a = 10;
    2. int i = a;//把包装拆成类型
    3. System.out.println(i);


    1. public static void main(String[] args) {
    2. Integer a = 100;
    3. Integer b = 100;
    4. System.out.println(a == b);
    5. Integer a1 = 200;
    6. Integer b1 = 200;
    7. System.out.println(a1 == b1);
    8. }

    输出结果:true false

    为什么第二个结果是false呢?我们返回来看看valueOf定义的范围

    说明:IntegerCache.low = -128, 前面加个负号负负得正

     100还在这个范围里面,true就是理所当然

    但是200明显超过最大值,数组越界,每次Integer 变量 就会产生新的对象,每个新的对象就会产生新的地址,两个地址不一样就导致 false


    泛型:适用于很多很多类型

    实现一个类,类中包含一个数组成员,使得数组中可以存放任何类型的数据,也可以根据成员方法返回数组中某个下标的值

    1. class MyArray {
    2. public Object[] array = new Object[10];
    3. //默认放到数组的最后一个位置
    4. public void setValue(int pos, Object val) {
    5. array[pos] = val;
    6. }
    7. public Object getValue(int pos) {
    8. return array[pos];
    9. }

    明明我拿1去找hello这个字符串,为什么找不到?因为getValue返回值是Object,所以我们需要进行强转

    String str = (String)myArray.getValue(1);//这样就行啦!

    但是很麻烦的一点,每一次找value都要知道这个value是什么类型,如果有成千上百对数据,找起来不就炒鸡麻烦

    为了解决这个问题,我们引入泛型

    1. /**
    2. *
    3. * @param 当前类是一个泛型类,只是一个占位符
    4. * 注意:<>里面的类型必须是包装型,不能是简单数据类型
    5. */
    6. class MyArray {
    7. //public T[] array = new T[10];
    8. //默认放到数组的最后一个位置
    9. public Object[] array = new Object[10];
    10. public void setValue(int pos, T val) {
    11. array[pos] = val;
    12. }
    13. public T getValue(int pos) {
    14. return (T)array[pos];//把返回的类型 强转为指定类型
    15. }
    1. public static void main(String[] args) {
    2. MyArray myArray = new MyArray();//只能放包装类
    3. myArray.setValue(0,10);
    4. myArray.setValue(1,100);
    5. int a = myArray.getValue(1);
    6. System.out.println(a);
    7. MyArray myArray2 = new MyArray<>();
    8. myArray2.setValue(0,"abcd");
    9. myArray2.setValue(1,"efg");
    10. String ret = myArray2.getValue(1);
    11. System.out.println(ret);
    12. }

    以前我们只能传入值,但是现在我们可以传入指定的类型

    不能new泛型类型的数组,泛型是编译时期存在的,当程序运行起来到JVM之后,就没有泛型的概念了,new T 无法确定

    泛型在编译的时候有个擦除机制,擦除成了Object

    现在又有问题了

    1 、那为什么, T[] ts = new T[5]; 是不对的,编译的时候,替换为 Object ,不是相当于: Object[] ts = new Object[5]吗?
    2、还是说,我们把泛型类型数组实例化一下就行了?
    像这样:
    public T[] array = (T[])new Object[10];

    这其实是一个欺骗编译器的小伎俩,瞒天过海让编译器以为是Object类型就让你过了

    倘若我在MyArray里面加多一个方法,阁下又该如何应对

    1. public static void main(String[] args) {
    2. MyArray myArray1 = new MyArray<>();
    3. //[1, "fdsfa" ]
    4. Object[] integers = myArray1.getArray();
    5. }

    程序报错

    即便强转也无济于事

    Object[] integers = (Object[]) myArray1.getArray();

    因为返回的Object数组里面肯能存放的是任何的数据类型,可能是String, Person之类的,把这些数据类型通通变成Integer,编译器认为不安全就不给过

        public Object[] array = new Object[10];

    所以这么写就行啦!


    泛型的上界

    1. //T一定是Number或者Number的子类
    2. class TestGeneric extends Number>{
    3. }

     

     Integer 和 Double都是Number的子类,传入不会报错;但是String不是Number的子类,所以传入报错

    Number是Integer和Double的上界,也就是父类


    写一个泛型类,求一个数组中的最大值

    欸,这不对吧,怎么报错啊

    这里的T一定是引用数据类型,最终被擦除为了Object类,而Object是不能进行比较的

    那怎么约束这个T让它可以用来比较大小呢

    class Algf>

    这句话表示T一定是实现了Comparable接口的,在下面我们可以调用compareTo方法

    1. class Algextends Comparable>{
    2. public T findMax(T[] array){
    3. T max = array[0];
    4. for (int i = 1; i < array.length; i++) {
    5. if(max.compareTo(array[i])< 0){
    6. max = array[i];
    7. }
    8. }
    9. return max;
    10. }
    11. }

    在main函数里面调用

     

    如果想用Person类型的话,直接调用那指定是报错的

    在Person类实现这个接口并重写方法就没问题了

    1. class Person implements Comparable{
    2. @Override
    3. public int compareTo(Person o) {
    4. return 0;
    5. }
    6. }

    泛型方法,把放在类实现的接口语句扔到方法的访问限定符的后面就行了

    1. class Alg2{
    2. publicextends Comparable> T findMax(T[] array){
    3. T max = array[0];
    4. for (int i = 1; i < array.length; i++) {
    5. if(max.compareTo(array[i])< 0){
    6. max = array[i];
    7. }
    8. }
    9. return max;
    10. }
    11. }
    1. Alg2 alg2 = new Alg2();
    2. Integer[] integers1 = {1,2,3,4,5,6,7};
    3. //类型推导:根据实参传值来推导此时的类型,所以前面可以不用指定类型
    4. System.out.println(alg2.findMax(integers1));

  • 相关阅读:
    【外汇天眼】MT4 vs MT5:哪个更适合外汇初学者
    【C 语言考试真题】详解(一)
    期货开户后需要银期转账绑定
    俄罗斯方块游戏开发教程5:形状碰撞检测(下)
    数据库缓存一致性研究
    python LeetCode 刷题记录 21
    记一次 ERROR scheduler.AsyncEventQueue: Dropping event from queue shared导致OOM
    喜报 | 再度中标南网项目!AR 开启电力远程运维新智慧
    android安全测评修复小记(备用)
    如何快速写出一篇核心论文?
  • 原文地址:https://blog.csdn.net/hellg/article/details/133105049