引入
在-->Java详解--泛型-CSDN博客这篇文章中,我们已经详细介绍了有关Java泛型的相关理论,其中包括引入泛型的原因,以及使用泛型时的注意事项,那么在这里,我们从泛型实现原理、实操,以及泛型相关引申角度再析Java泛型。
示例(帮理解)
还是以一个例子开始,在Java详解--泛型-CSDN博客这篇文章中,引入的示例是一个可以被申请任意类型的队列类,这里引入一个能拓展改变空间大小以及数据类型的数组:
package tree;
import java.util.*;//(几乎涵盖所有算法需要的类)
//import java.util.ArrayList; (被上面涵盖了)
public class Test {
public static void main(String[] args) {
String[] arr=new String[100];//定长数组【创建的瞬间,大小就已经固定不变了】
ArrayList<String> xx=new ArrayList<>();//可拓展的数组
xx.add("shs1"); //存入泛型数组的函数
xx.add("hue2");
xx.add("hue3");
xx.add("hue4");
xx.add("hue5");
xx.add("hue6");
xx.add("hue7");
xx.add("hue8");
String x=xx.get(1); //取出来xx[1]
System.out.println(x);
xx.remove(2); //删除xx[2],删除后,后面的会自动向前覆盖
int num=xx.size(); //size()获取String类型长度;xx.length()获取数字类型数组长度
System.out.println(xx.toString());//打印的方法
// ===========================
ArrayList<Stack> z=new ArrayList<>(); //这里是我的另一个类文件
//可以向里面放任何类型(泛型)
}
}
【注:调用Java自带的ArrayList类需要引用"import java.util.ArrayList",也可以直接引用"import java.util.*",这个里面涵盖了Java算法大多数需要用到的类】
【注:获取数组长度时用到的函数方法(这里适用于Java方法没有被重写的情况)
- 数组:使用 length 属性来获取数组的长度。
- 字符串:使用 length() 方法来获取字符串的长度。
- 集合:使用 size() 方法来获取集合的大小。
】
⭐
根据这个例子和注释,可以得出一个结论:泛型内不仅可以放数据类型,还可以申请一个类的类型数组,并在里面add进它本身以及子孙后代类的类:
【注:Animal是一个父类,Dog、Fish都是Animal的子类】
打印数组:
可以用自带的toString方法,也可以用下面两种遍历方法:
①推荐这种
for(String x:xx){
System.out.println(x);
}
②和上面本质一样
for(int i=0;i<xx.size();i++){
System.out.println(xx.get(i));
}
多维数组
只需要将<>里面嵌套填写另一个泛型,嵌套n个就是n-1维数组:
ArrayList<Integer> xx=new ArrayList<>();//一维整数
ArrayList<ArrayList<Integer>> xx=new ArrayList<>();//二维整数
ArrayList<ArrayList<ArrayList<Object>>> xx=new ArrayList<>();//三维某个数组
泛型的包装类
注意,泛型ArrayList<>的尖括号里面只能放引用类型,而不能放char,int等基础类型,所以引用类型String就填String,同理int[],String[]这种数组类型也可以直接填入(数组本身就是引用类型),而如下基础类型则对应如下包装类:
int---Integer
long--Long
float--Float
double--Double
char--Character
<>里面必须填上述,但是在其他方面可以照旧使用:
如下:
【int类型的数据和Integer类型的数据都可以照旧被add进Integer类型的泛型数组中】
比较(⭐易混淆)
①都返回true
因为数据和句柄都相同
②⭐128陷阱
比较int类型的k1和k2所比较的是值,但是Integer类型的k3和k4比较的是句柄,不仅是Integer有这个问题,其他包装类也有这个问题:
在包装类中,如果数值相同,但是不在-128~127的范围中,则句柄指向的并不是一个对象,就会返回false;
那么如何比较这些包装类指向的数值呢?
要将句柄指向的位置先转化成数据,再进行比较:
如下:
泛型的实现原理
在实现泛型的应用后,不妨来看一眼泛型的内部原理本质就是这篇文章-->Java详解--泛型-CSDN博客:
这就是刚才实操时用到的那些方法:
package tree;
import java.util.*;
public class Test<泛型> {
private 泛型[] arr=(泛型[]) new Object[10];//强转一下
private int flag=0;
public void add(泛型 x){
//满了扩容
if(flag==arr.length){
泛型[] arrnew=(泛型[]) new Object[arr.length*2];
for(int i=0;i<arr.length;i++){
arrnew[i]=arr[i];
}
arr=arrnew;
}
arr[flag++]=x;
}
public 泛型 get(int index){
if(index<flag){
return arr[index];
}else{
return null;
}
}
//删除元素(本质还是覆盖)
public void remove(int index){
for(int i=index;i<flag-1;i++){
arr[i]=arr[i+1];
}
flag--;
}
获取长度
public int size(){
return flag;
}
}
HashMap泛型
说完泛型后,再额外引入一个特殊的泛型,同时也是最常用的泛型--HashMap泛型,这个概念在
-->每日小题--独一无二的出现次数(内含HashMap释)-CSDN博客这篇文章中已经引出了定义以及相关方法,和使用,再次重析:
HashMap<>是“key value”类型的:
【有一个特点,存或取数据的时间都是O(1)】
示例
package tree;
import java.util.*;
public class Test {
public static void main(String[] args) {
HashMap<String,Integer> map=new HashMap<>();
map.put("张三",20);
map.put("小红",10);
map.put("小明",12);
map.put("红太狼",30);
Integer x=map.get("张三");//获取的值是Integer类型的,所以要用Integer来接收
System.out.println(x);
int y=map.get("张三");//由于Integer是int的包装类,所以本质相同
System.out.println(y);
}
}
动态规划大多数都是动态规划,困难级别的动态规划都需要hashmap()检测去重提升时间性能---困难级别的算法题大多数离不开HashMap.
HashMap遍历的两种方式:
(*^_^*)通过以上析,对Java泛型的使用有把握了吗?o(* ̄▽ ̄*)ブ
标签:详析,--,ArrayList,add,xx,数组,泛型 From: https://blog.csdn.net/m0_74977981/article/details/144133050