java数据结构:时间/空间复杂度、包装类、泛型

算法的效率主要从时间复杂度和空间复杂度来分析

1.时间复杂度:算法中基本操作的执行次数

一般看最坏执行了多少次

表示方法:大O的渐进表示法
1.用常数1取代运行时间中的所有加法常数
2.只保留最高阶项
3.如果最高阶项存在且不是1,去掉与它相乘的常数。

在这里插入图片描述
Eg:
1.在这里插入图片描述
2.在这里插入图片描述

3.在这里插入图片描述
4.在这里插入图片描述
5.在这里插入图片描述

6.在这里插入图片描述

7.在这里插入图片描述
O(1) < O(logN)< O(N)< O(N*logN)< O(N的平方)

空间复杂度:变量的个数

1.在这里插入图片描述
2.在这里插入图片描述
3.在这里插入图片描述

包装类

在这里插入图片描述
除了char和int,其他都是首字母大写。

装箱和拆箱

装箱:

        //装箱:将基本数据类型 转换 为包装类
        int a = 10;
        Integer b = a;//    自动/隐式装箱
        System.out.println(b);

        int c = 10;
        Integer d = Integer.valueOf(c);//显示装箱
        System.out.println(d);

拆箱:

        //拆箱:将包装类 转换为基本数据类型
        Integer a = new Integer(10);
        int b = a;//       自动/隐式拆箱
        System.out.println(b);

        int c = a.intValue();//显示拆箱
        System.out.println(c);
        double d = a.doubleValue();//拆箱可以指定类型
        System.out.println(d);

一道面试题:

        Integer a = 100;
        Integer b = 100;
        System.out.println(a == b);//true

        Integer c = 200;
        Integer d = 200;
        System.out.println(c == d);//false

在这里插入图片描述
i最小为-128,最大为127, 200超过了127,所以false。
在这里插入图片描述

泛型类

主要目的是指定当前这个容器,持有什么类型的对象,让编译器检查。
只需要把类型作为参数传递,需要什么类型,传入什么类型。

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

class MyArray1 {
    public Object[] myArray = new Object[10];//所有类的父类Object类

    public void set(int pos, Object val) {//因为要满足任何类型的值,所以用Object
        myArray[pos] = val;
    }

    public Object get(int pos) {
        return myArray[pos];
    }


}
public class Test3 {
    public static void main(String[] args) {
        MyArray1 myArray = new MyArray1();//实例化一个对象

        myArray.set(0,10);
        myArray.set(1,"hello");
        int a = (int)myArray.get(0);//这里需要强转,因为返回的是Object类
        System.out.println(a);
    }
}
class MyArray1<T> {//代表当前类是一个泛型类
    public Object[] array = new Object[10];
    //public T[] array = new T[10];//不允许实例化一个泛型数组

    public void set(int pos, T val) {
        array[pos] = val;
    }

    public T get(int pos) {
        return (T)array[pos];//返回时已经强转为自己指定的类型
    }

}
public class Test3 {
    public static void main(String[] args) {
        MyArray<String> myArray = new MyArray<>();//尖括号中只能是引用类型,不能是基本类型
        myArray.set(0,"hello");
        myArray.set(1,"world");
        //myArray.set(1,10);已经指定为String类型,不能添加其他类型
        String str = myArray.get(0);//此时已经不需要强转
        System.out.println(str);
    }
}

为什么不允许实例化一个泛型类数组?

class MyArray<T> {
    public T[] array = (T[]) new Object[10];
        public void set(int pos, T val) {
            array[pos] = val;
        }

        public T get(int pos) {
            return (T) array[pos];
        }

        //public T[] getArray() {
        //     return array;
        // }
        public Object[] getArray() {
               return array;
        }
}
public class Test2 {
    public static void main(String[] args) {
        MyArray<Integer> myArray = new MyArray<>();
        Integer[] array1 = myArray.getArray();
    }
}

在这里插入图片描述
在这里插入图片描述

将Object[]分配给Integer[]引用之后呢,程序会报错,返回的Object数组里面,可能存放的是任何类型的数据类型,可能String,可能Person,运行的时候直接转给Integer类型的数组,编译器认为不安全。

泛型类的编译:

在编译的过程中,将所有的T替换成Object,称为擦除机制。
运行的时候没有泛型这样的概念,泛型的擦除机制只存在于编译期间。

泛型的上界

在定义泛型类时,有时需要对传入的类型变量做一定的约束,可以通过类型边界来约束。
eg:

class MyArray1<T extends Number> {//T是Number 或 T是Number的子类

}
public class Test4 {
    public static void main(String[] args) {
        MyArray1<String> myArray1 = new MyArray1<>();//编译错误,String不是Number的子类
        MyArray1<Integer> myArray11 = new MyArray1<>();//正常
    }
}
//class Alg<T> {
//    public T finaMax(T[] array) {
//        T max = array[0];
//        for (int i = 0; i < array.length; i++) {
            if(array[i] > max) {//两个Object不能进行比较
                max = array[i];
            }
//        }
//    }
// }


    //写一个泛型类,实现一个方法,这个方法是求指定类型数组的最大值?
class Alg1<T extends Comparable<T>> {//T一定是实现Comparable接口的  上界   extends在这里是拓展的意思
    public T finaMax(T[] array) {
        T max = array[0];
        for (int i = 0; i < array.length; i++) {
            if(array[i].compareTo(max) > 0) {
                max = array[i];
            }
        }
        return max;
    }
}
class Alg2 {
    //泛型方法
    public <T extends Comparable<T>> T findMax(T[] array) {
        T max = array[0];
        for (int i = 0; i < array.length; i++) {
            if(array[i].compareTo(max) > 0) {
                max = array[i];
            }
        }
        return max;
    }

}
class A implements Comparable<A>{//必须实现comparable接口,main方法中Alg1<A>才正确

    @Override
    public int compareTo(A o) {
        return 0;//必须重写comparable方法
    }
}
public class Test3 {
    public static void main1(String[] args) {
        Alg1<Integer> alg1 = new Alg1<>();
        //  Alg1<A> alg12 = new Alg1<>();
        //  Alg1<String> alg12 = new Alg1<>();
        Integer[] array = {10,21,34,56,67,98};
        Integer ret = alg1.finaMax(array);
        System.out.println(ret);
    }

    public static void main2(String[] args) {
        Alg2 alg2 = new Alg2();//如果不想实例化对象,直接将方法改为静态方法,调用方法时用类名。
        Integer[] array = {10,21,34,56,67,98};
        Integer ret = alg2.<Integer>findMax(array);//尖括号及里面的内容可不写,方法调用时会推导你传入的是什么类型的参数
        System.out.println(ret);
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值