前言
在JAVA的容器中存放的只能是引用类型的数据,基本数据类型进去之后会被自动装箱。我们在声明容器时,使用泛型指明其中的类型时,类型必须指明为引用类型。如下面的声明是错误的
List<int> list=new ArrayList<>();
还未编译时就会报错。
这样的问题其实在java中相当困扰人,java为了不破坏封装性,更好的体现面向对象的特性,要知道基本数据类型是没有属性与方法的,所以尽可能的不在类中使用基本数据类型。
java中的包装类
java在设计的时候为每个基本数据类型设计包装类(Wrapper Class)
基本数据类型 | 包装类 |
---|---|
byte | Byte |
boolean | Boolean |
short | Short |
char | Character |
int | Integer |
long | Long |
float | Float |
double | Double |
包装类与基本数据类型之间的转换(下面的转换是不完整的,很多情况不能使用此此方法来做):
基本类型变量------------String.valueof()------------>字符串
基本类型变量<------------WrapperClass.parseXxx(string)------------字符串
对于java的包装类与基本类型可以自动转换,分别叫做自动封箱与自动解封
这里对于基本数据类型与包装类还牵扯到一个存储结构的问题:
我们知道java中的引用类型一般都放在堆中,但是对于基本数据类型,java一般是直接放在栈中的。关于堆和栈为什么要分开,以及分开有什么好处?
堆栈分离
堆和栈为什么要分开?
1、栈主要用来处理逻辑功能,堆代表存储数据,这样做的好处就是符合设计模式中的对象之间的松耦合,把栈和堆分离开来,可以使处理逻辑的条理更加清晰
2、堆中的数据可以被多个栈中的数据共享,节省了相应的存储空间。从线程共享的方面来看,堆和栈的分离,可以使堆的信息是线程共享(或者说是栈共享的)的,这样就为多线程同时访问一个对象提供了可能。而这样方式对于数据交互是有效的(通过共享内存),而且堆中的共享常量和缓存可以给多个栈访问,节约了空间。
3、栈只能向上增长,限制了栈的存储能力,而堆可以动态增长。
4、对象的大小是不可估量的,但是一个对象的引用只有4byte左右
为什么不把基本数据类型放在堆中?
1、基本数据类型占用的空间一般是1-8个字节,需要占用空间比较少
2、基本数据类型不存在自动增长,长度是固定的,因此存在堆中没有意义,还会浪费空间
String类型的容器转数据
对于String类型的ArrayLIst数据转化成String类型的数组
String [] arr=list.toArray(new String[list.length()]);
Integer类型的容器转数组
对于Integer类型的ArrayList转化为int类型的数组
由于String类型本身就是一个类所以转换器来十分简单,但是对于int类型的数组而言,需要由Integer类型转化为int类型。有两种转换方式。
可以查看
https://blog.csdn.net/qq_41115379/article/details/118416364
https://www.cnblogs.com/oldhands/p/11847039.html?ivk_sa=1024320u
其实一维数组看了这么多,用方法转换也好,循环暴力赋值也罢,这样的方法其实没什么差别
更难的在于如果我们声明了二维动态数组,在想把二维动态数组转化为普通数组的时候就会有点困难,假如我们采取的是这种声明方式
List<List<Integer>>=new ArrayList<ArrayList<Integer>>();
其实,我们清楚的是在容器中不能包含基本数据类型,但是这样的声明方式是正确的
List<int[]> res = new ArrayList<>();
return res.toArray(new int[res.size()][]);
让容器中保存的是int[]这样的数据类型。
总结:使用toArray时的三种方式
toArray(T[])方法,其中的参数对于我们来说并不重要,不是决定返回值数组大小的,而是确保这样一个类型为数组类型
//list是一个容纳long类型数据的容器。
Long[] l = new Long[total size];
list.toArray(l);
Long[] l = list.toArray(new Long[0]);
Long[] a = new Long[<total size>];
Long[] l = list.toArray(a);
1).参数指定空数组,节省空间
String[] y = x.toArray(new String[0]);
2).指定大数组参数浪费时间,采用反射机制
String[] y = x.toArray(new String[100]); //假设数组size大于100
3).姑且认为最好的
String[] y = x.toArray(new String[x.size()]);