注意一:时间复杂度从小到大排列
O( 1 ) < O( log n ) < O( n ) < O( n log n ) < O( n^2 )
注意:
接口与接口之间的关系: extends
接口与类之间的关系: implements
注意二:泛型
泛型:泛型就是将类型进行参数化,将类型作为参数进行传递。
找一个数组可以存放所有数据类型的数据,那么这个数组的类型必然是Object 类型的数组,
- 因为Object 是所有类的父类,并且它可以接受所有的数据类型包括:类,接口,数组。
- 引用数据类型大部分都是类或接口,String类等,他们的父类是Object类
- 基本数据类型,有拆箱和装箱的概念
public static void main(String[] args) {
Object[] array = {1,2,3,"hello"};
String[] array2 = (String[]) array; //现在不报错但是运行的时候报错
}
//只要是Object类型的数组,就不让强转成其他类型。但是单个类是可以转的。
package demo;
class Arrayer{
Object[] array = new Object[10]; //数组中每个元素都是Object类型
public void setArray(int pos, Object value){
array[pos] = value;
}
public Object getArray(int pos){
return array[pos];
}
}
public class Test2 {
public static void main(String[] args) {
Arrayer arrayer = new Arrayer();
arrayer.setArray(5,"hello");
arrayer.setArray(4,20);
//String str = arrayer.getArray(5); //error
//getArray()方法返回的是Object 不会自动转化成String类型,要手动强转
//注意区别这句话 : 只要是Object类型的数组,就不让强转成其他类型。但是单个类是可以转的。
String str = (String) arrayer.getArray(5);//right
System.out.println(str);
System.out.println(arrayer.getArray(1));
}
}
// hello null
这样我们会发现一个问题,向Object类型的数组中 传数据是比较方便的,但是取的时候是非常困难的,我们取的时候要找个变量来接收,
但是数组中元素的类型是Object类型,所以每次都要根据接受变量的类型进行强制类型转换,这样做是非常不智能的。低效的。
改进:(使用泛型)
package demo;
class Arrayer2<T>{ // T 类型形参列表 表示的是传递的类型 可以指定多个类型 < > 占位符 表示当前类是泛型类
T[] array = (T[]) new Object[10]; //注意这个地方有问题
public void setArray(int pos, T value){
array[pos] = value;
}
public T getArray(int pos){
return array[pos];
}
}
public class Test3 {
public static void main(String[] args) {
Arrayer2<Integer> arrayer = new Arrayer2<Integer>();
Arrayer2<String> arrayer2 = new Arrayer2<String>();
arrayer.setArray(0,12);
arrayer2.setArray(0,"nihao");
arrayer2.setArray(1,"hhh");
System.out.println(arrayer.getArray(0));
System.out.println(arrayer2.getArray(0));
System.out.println(arrayer2.getArray(1));
}
}
/*
12
nihao
hhh
*/
我们之前传递的是变量的值,现在我们传递的是变量的类型了。
泛型存在的两个最大的意义:
- 1:在存放元素的时候会进行类型的检查。
- 2:在取出元素的时候会进行类型的转换,不用自己再强转了。
- 这两步都是在编译的时候完成的,因为在程序运行的时候,没有泛型这个概念。泛型主要是程序编译时的一种机制 --》擦除机制。
注意:< 里面一定是类类型 ,不可以是基本数据类型 > < int > //error
java泛型机制是在编译时期实现的,编译器生成的字节码在运行期间并不包括泛型的类型信息
注意三:Object类型的数组是不可以强转成其他类型的会报错
package demo;
import java.util.Arrays;
class Arrayer2<T>{
//T[] array1 = new T[10]; error
T[] array = (T[]) new Object[10]; //注意这个地方有问题
public void setArray(int pos, T value){
array[pos] = value;
}
public T getArray(int pos){
return array[pos];
}
public T[] getArray(){
return array; //注意这是返回一个Object类型的数组
}
}
public class Test3 {
public static void main(String[] args) {
Arrayer2<Integer> arrayer = new Arrayer2<Integer>();
Arrayer2<String> arrayer2 = new Arrayer2<String>();
arrayer.setArray(0,12);
arrayer2.setArray(0,"nihao");
arrayer2.setArray(1,"hhh");
Integer[] ret = arrayer.getArray(); //Object类型的数组是不可以强转成其他类型的会报错
//ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;at demo.Test3.main(Test3.java:31)
}
}
//T[] array1 = new T[10]; error
T[] array = (T[]) new Object[10]; //注意这个地方有问题
//你所实例化的一个数组不是具体类型的
import java.lang.reflect.Array;
public class Test4<T> {
T[] array;
public Test4(Class<T> clazz,int capicity){
array = (T[])Array.newInstance(clazz,capicity);
}
}
public class Test {
public static void main(String[] args) {
Test4<Integer> test4 = new Test4<Integer>(Integer.class ,10);
}
}
//这样写是正确的,涉及到反射的知识,作为了解
//这样你所实例化的一个数组是具体类型的
注意四:泛型上界
你会发现只接受 Number 的子类型作为 E 的类型实参,别的都超出Number的边界了。
package demo1;
public class Alg<T extends Comparable<T>> { //特殊:泛型上界 T类型必须是实现了Comparable接口的
//寻找数组中的最大值
public T findMax(T[] array){
T max = array[0];
for (int i = 1; i < array.length; i++) {
if(max.compareTo(array[i]) < 0){
max = array[i];
}
}
return max;
}
}
class Person implements Comparable<Person> {
private int age;
private String name;
public Person(int age, String name){
this.name = name;
this.age = age;
}
//重写compareT方法 ,你想比较啥就写啥
@Override
public int compareTo(Person o) {
return this.age - o.age;
}
//重写toString方法
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
class Test{
public static void main(String[] args) {
Integer[] array = {1,2,3,4,5,6};
Alg<Integer> alg = new Alg<>();
System.out.println(alg.findMax(array));
Person[] person = {
new Person(10,"xiaobai"),
new Person(20,"xiaohong"),
new Person(5,"xiaohuang"),
new Person(30,"dabai")
};
Alg<Person> alg1 = new Alg<Person>();
Person ret = alg1.findMax(person);
System.out.println(ret);
}
}
//6
//Person{age=30, name='dabai'}
注意五:泛型方法
(1):泛型静态方法
package demo2;
public class Alg {
public static<T extends Comparable<T>> T findmax(T[] array){
T max = null;
for(int i = 0; i < array.length - 1; i++){
if(array[i].compareTo(array[i+1]) < 0){
max = array[i + 1];
}
}
return max;
}
}
class Test{
public static void main(String[] args) {
Integer[] array = {1,2,3,4,5,6,7,8,9,10};
Integer ret = Alg.findmax(array);
//Integer ret = Alg.<Integer>findmax(array);
//这两种写法都是可以的,只不过第一种省去的类型参数是通过传参array来判断的.
System.out.println(ret);
}
}
// 10
(2):泛型方法:
package demo2;
import java.util.Arrays;
public class Alg2 {
public <T extends Comparable<T>> void func(T[] array){
for (int i = 0; i < array.length - 1; i++) {
if(array[i].compareTo(array[i+1]) < 0){ //会调用相应对象的compareTo方法
T temp = array[i];
array[i] = array[i+1];
array[i+1] = temp;
}
}//泛型方法,对任意类型的数组进行排序
}
}
class Person implements Comparable<Person> {
private String name;
public Person(String name){
this.name = name;
}
@Override
public int compareTo(Person o) {
return this.name.length() - o.name.length();//重写了compareTo方法,以这个方式进行比较
}
@Override
public String toString() { //重写了toString方法,Arrays.toString(person)直接调用相应对象当中的toString方法
return "Person{" +
"name='" + name + '\'' +
'}';
}
}//Person类
class Test1{
public static void main(String[] args) {
Person[] person = {
new Person("xiaohong"),
new Person("xiaohuang"),
new Person("xiaohua")
};
Alg2 alg2 = new Alg2();
alg2.func(person);
System.out.println(Arrays.toString(person));
}
}
//[Person{name='xiaohuang'}, Person{name='xiaohong'}, Person{name='xiaohua'}]
泛型静态方法不用new对象直接调用。
注意六:通配符
package demo4;
public class Messager<T> {
private T ret;
public void setRet(T ret){
this.ret = ret;
}
public T getRet(){
return this.ret;
}
}
class test{
public static void main(String[] args) {
Messager<Integer> messager = new Messager<>();
messager.setRet(10);
func(messager);
Messager<String> messager2 = new Messager<>();
messager2.setRet("xiaobai");
func(messager2);
}
public static void func(Messager<?> messager){
//可以接收所有的泛型类型,但是又不能够让用户随意修改。这种情况就需要使用通配符"?"来处理
System.out.println(messager.getRet());
//messager.setRet("hhh") error 不可以往里面放,因为也不知到放什么类型
}
}
public static void func(Messager<Integer> messager){
System.out.println(messager.getRet());
}
public static void func(Messager<String> messager){
System.out.println(messager.getRet());
}
//这两段代码是一样的,擦除完之后如下
public static void func(Messager<Object> messager){
System.out.println(messager.getRet());
}
public static void func(Messager<Object> messager){
System.out.println(messager.getRet());
}