数据结构的基本框架以及泛型

集合框架

Java的集合框架,Java Collection Framework 又被称为容器container, 定义在java.util包下的一组 interfaces 和其实现类 classes

interface: 接口
abstracb class: 抽象类
class: 类

在这里插入图片描述
这一张图片里面.,描述了Java里面,比较重要的类与类, 类与接口之间的关系.

在这里插入图片描述

在这两个图里面,最重要的接口有4个,分别是list, queue,set 以及 map,其他的类都是实现这些接口的

复杂度

在我们写代码的时候,我们是会讲究一个效率问题的,被用复杂度来表示,其中也分为时间复杂度以及空间复杂度,这两个复杂度都是用: 大O的渐进表示法来表示的

复杂度肯定也是有分为最好情况,最坏情况以及平均情况的 ,但是我们一般在讨论的时候,我们都是要默认说最坏的情况.

大O的渐进表示法

1>用常数 1 取代时间中的所有加法常数
2>在修改后的运行次数函数中,只保留最高阶项
3>如果最高阶存在且不是 1 ,则去除与这个项目相乘的常数,得到的结果是大O阶

例如:
在这里插入图片描述
例如代码之中有这样一块循环,复杂度是按照最坏的情况考虑的,

for (int i = 0; i < N; i++) {
       for (int j = 0; j < N; j++) {
             count++;
        }
}

首先里面第一部分是这样一块代码,两个for循环套在一起,最坏的情况就是每个for会循环N次,所以这一块的复杂度就是N^2次

for (int i = 0; i < 2 * N; i++) {
           count++;
       }

第二部分里面,循环会有2N次,所以他的复杂度就是2N次

int m = 10;
        while ((m--) > 0){
            count++;
        }

第三部分就是一个while循环,可以看见m是10,所以这个循环最多进行10次,复杂度为10

最后的话我们就可以知道这个复杂度是O(N) = N^2 + 2 * N + 10
我们再根据大O的渐进法进行化简,O(N) = N^2就是代码的复杂度了

装包(箱)或者拆包(箱)

装包

Integer a =10;

int i = 5;
Integer b =i;

上面的代码是两种装包的写法
但是我们有两种装包的方式,一种是显式,一种是隐式装包

Integer a =10;
Integer aa = Integer.valueOf(10);

上面这两个就是不用的装包方式,a是一种隐式装包,在写的时候把valueof给隐藏起来了,没有显式出来
aa的话就是显式装包,在这个过程中,把valuof这个过程给写了出来

拆包

同样的,拆包也分为隐式的和显式的

Integer a =10;
int i = a;

想这个就是隐式的拆包

int aa = a.intValue();
double d = a.doubleValue();

像上面这两个就是显式的拆包,

从上面可以看出,对于拆包来说,隐式和显式的差别也就是在于value的差别

在这里插入图片描述
在这个截图上面,我们可以看出,定义了两组不同的包装类.但是有一组返回的是true,有一组返回的是false,这是为什么呢?
在这里插入图片描述
在这里插入图片描述
通过上面两个截图,调用valueof的底层源码可以看到,它的取值范围是在-128到127之间的,那也就是说我们的aa,以及bb是超出了这个范围的.
所以当aa,bb都取值200时候,他们都是创建了新的地址,所以地址是不同的

泛型

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

class MyArray<T>{
    public Object[] array = new Object[10];
    public void setvalue(int pos,T val){
        array[pos] = val;
    }
    public T getvalue(int pos){
        return (T)array[pos];
    }
}
public class Test {
    public static void main(String[] args) {
        MyArray<Integer> myArray = new MyArray<Integer>();
        myArray.setvalue(0,10);
        myArray.setvalue(1,100);
        int a = myArray.getvalue(1);
        System.out.println(a);


        
        MyArray<String> myArray1 = new MyArray<String>();
        myArray1.setvalue(0,"hello");
        myArray1.setvalue(1,"ko");
        String b = myArray1.getvalue(0);
        System.out.println(b);

像在上面就是个泛型的代码,在上面这个代码里面,我们可以发现,我们在输出的时候可以输出整数,也可以输出字符串,我们想输出其他的类型,只要创建一个新的对象就可以了
在这里插入图片描述
我们可以正常的输出a和b,就像泛型的概念说的"类中包含一个数组成员,使得数组中可以存放任何类型的数据"
像在泛型里面还要一点要注意
在这里插入图片描述
像我们在泛型里面创建对象的时候,我们不可以new一个泛型类型的数据,必须是Object类型的,因为泛型是在编译时期的一个概念,当程序运行起来到了JVM以后,就没有了泛型的概念

泛型在编译时期是如何编译的?
是采用了擦除机制,把T擦除成了Object!!!

泛型的上界

模板: class 泛型类名称 <类型形参 extends 类型边界> {

}

class TestGeneric<T extends Number>{
    
}

public class Test {
    public static void main(String[] args) {
        TestGeneric<Number> testGeneric = new TestGeneric<>();
        
    }
}

这上面就是泛型的一个使用模板
在这里插入图片描述
这上面的话是一个泛型取最大值的方法,但是我们可以看到在if的那个地方,会报错.
这是因为T一定是引用数据类型,最终被擦除为了Object类型,因为我们是要求最大值,所以这个T的类型一定是可比较的,所以我们要继承自Comparable接口,然后可以调用CompareTo进行比较
在这里插入图片描述
所以正确的我们if里面要像上图这样写才可以

class Alg<T extends Comparable<T>> {
    public T findMaxValue(T[] array) {
        T max = array[0];
        for (int i = 0; i < array.length; i++) {
            if (max.compareTo(array[i]) < 0) {
                max = array[i];
            }
        }
        return max;
    }
}


public class Test {
    public static void main(String[] args) {
        Alg<Integer> alg = new Alg<>();
        Integer[] integers = {1, 2, 3, 4, 5, 6, 7};
        Integer ret = alg.findMaxValue(integers);
        System.out.println(ret);
    }
}

在这里插入图片描述
完整的代码就是上面这样的,最大值也就是7

泛型方法求最大值

class Alg2{
    public static <T extends Comparable<T>> T findMaxValue(T[] array){
        T max = array[0];
        for (int i = 0; i < array.length; i++) {
            if (max.compareTo(array[i]) < 0){
                max = array[i];
            }
        }
        return max;
    }
}
public class Test {
    public static void main(String[] args) {
        Alg2 alg2 = new Alg2();
        Integer[] integers1 = {1,2,3,4,5,6,7};
        Integer ret1 = alg2.findMaxValue(integers1);
        System.out.println(ret1);
    }
 }


像上面这个方法的话,我们的Alg2里面,并没有写是什么类型的,但是为什么会知道现在是什么类型的呢,因为类型推导
会根据我们类型的传值,来推到此时的类型

  • 23
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小董是不懂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值