概念:
1、Java语言中的数组是一个引用数据类型,不属于基本数据类型。数组的父类是Object。
2、数组实际上是一个容器,可以同时容纳多个元素。(数组是一个数据的集合)
3、数组当中可以存储“基本数据类型”,也可以存储“引用数据类型”的数据。
4、数组因为是引用类型,所以数组对象在堆内存当中。(数组存储在堆内存中)
5、数组当中如果存储的是java对象的话,实际上存储的是对象的“引用”(内存地址)。
6、数组一旦建立,在java中规定,长度不可变。(数组长度不可变)
7、数组的分类:一维数组、二维数组、三维数组、多维数组。。。。(一维数组使用屁频率较多,二维数组偶尔使用)
8、所有数组对象都有Length属性(java自带),用来获取数组中元素的个数。
9、java中的数据要求数组元素类型统一,比如int类型的数组只能储存int类型。
10、数组在内存方面储存的时候,数组中的元素内存地址是连续的。内存地址连续是数组存储元素的特点,数据实际上是一种简单的数据结构。
11、所有的数组都是拿“第一个小方块的内存地址”作为整个数组对象的内存空间。
12、数组结构这种数据结构的优缺点:
优点:查询/查找/检索某个下标上的元素时效率极高。可以说是查询效率最高的一个数据结构。
为什么检索效率高?
第一:每个对象的内存地址在空间储存上是连续的。
第二:每一个元素类型相同,所以占用的空间大小相同。
第三:知道第一个元素的内存地址,知道每一个元素占用空间的大小,有知道下标,所以通过一个数学表达式就可以计算出某个元素的内存地址。直接通过内存地址定位元素,数组的检索效率是最高的。
缺点:
第一:由于为了保证数组中每个元素的内存地址连续,所以在数组上随即删除或者增加元素的时候效率低,因为随机增删元素会涉及到后面元素统一向前或者向后位移的操作。
第二:数组不能存储大数据量,为什么?
因为很难在内存空间上找到一块特别大的连续的内存空间。
注意:对于最后一个元素的增删,是没有效率影响的。
13、怎么声明/定义一个一维数组?
语法格式:
int [] array1;
double [] array2;
boolean [] array3;
String [] array4;
Object [] array5;
14、怎么初始化一维数组?
包括两种方法:静态初始化一维数组、动态初始化一维数组
静态初始化语法格式:
int [] array = {100,2100,300,55};
动态初始化语法格式:
int [] array = new int [5];//初始化一个5个长度的int类型数组,每个元素默认值0
String [] arrat = new String[6];//初始化一个6个长度的String类型数组,每个元素默 认值是null;
用静态初始化数组进行存、取以及遍历
public class ArrayTest01 {
public static void main(String[] args) {
//声明一个数组,使用静态初始化方式
int [] a = {
10,20,50,222,555,765};
//所有数组对象都有Length属性
System.out.println("数组中元素的个数 :" + a.length);
//数组每个元素都有下标
//通过下标对数组中的元素进行存和取。
//取
System.out.println("第一个元素" + a[0]);
System.out.println("最后一个元素" + a[5]);
System.out.println("最后一个元素" + a[a.length - 1]);
//存
//第一个最后一个改为110和990
a[0] = 110;
a[a.length -1]= 990;
System.out.println("第一个元素" + a[0]);
System.out.println("最后一个元素" + a[a.length - 1]);
//一维数组怎么遍历?
for (int i = 0;i<=a.length-1;i++){
System.out.println(a[i]);
}
//110
//20
//50
//222
//555
//990
//下标为6表示第七元素,第七个元素没有,下标越界了,会出现什么问题?
//System.out.println(a[6]);//ArrayIndexOutOfBoundsException(著名异常:数组下标越界异常。)
//从数组最后一元素遍历到第一个元素
for (int t = a.length-1; t >= 0; t--) {
System.out.println("颠倒顺序输出" + a[t]);
}
}
}
动态初始化数组进行读、写以及遍历
public class ArrayTest02 {
public static void main(String[] args) {
//声明一个数组,采用动态初始化的方式创建
int[] a = new int[4];
//遍历数组
for (int i =0;i<a.length;i++){
System.out.println("数组中下标为"+ i + "的元素是" + a[i]);
// 数组中下标为0的元素是0
// 数组中下标为1的元素是0
// 数组中下标为2的元素是0
// 数组中下标为3的元素是0
/*
关于每个基本数据类型的初始值:
数据类型 默认值
--------------------------
byte 0
short 0
int 0
long 0L
float 0.0F
double 0.0
boolean false
char \u0000
引用 null
*/
}
//动态赋值
a[0]=1;
a[1]=100;
a[2]=111;
a[3]=222;
for (int i =0;i<a.length;i++) {
System.out.println("数组中下标为" + i + "的元素是" + a[i]);
}
//初始化一个Object类型的数组,采用动态数组初始化方式
Object[] objs = new Object[3];
for (int i =0;i<objs.length;i++){
System.out.println(objs[i]);
}
//null
//null
//null
//存储Object,采用静态初始化
Object o1 = new Object();
Object o2 = new Object();
Object o3= new Object();
Object[] objects = {
o1,o2,o3};
for (int t = 0; t < objects.length ;t++){
System.out.println(objects[t]);
}
//结果
/*java.lang.Object@7f31245a
java.lang.Object@6d6f6e28
java.lang.Object@135fbaa4*/
}
}
当方法中是一个数组的时候怎么传参数?
//当方法是一个数组的时候,怎么传参数
public class ArrayTest03 {
public static void main(String[] args) {
//调用方法传一个数组
int[] x = {
1,2,3,4};
printArray(x);
//创建String数组
String[] strs = {
"abc","def","hehe","haha"};
printArray(strs);
System.out.println("============================");
//错误写法
//printArray({1,2,3,4});
//如果直接传递一个数组的值的话,语法需要这样写
printArray(new int[]{
1,2,3,4});
String[] strArray = new String[10];
printArray(strArray);//10个null
}
public static void printArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
public static void printArray(String[] args) {
for (int i = 0; i < args.length; i++) {
System.out.println("String数组中的元素" + args[i]);
}
}
}
//结果
/*
1
2
3
4
String数组中的元素abc
String数组中的元素def
String数组中的元素hehe
String数组中的元素haha
============================
1
2
3
4
String数组中的元素null
String数组中的元素null
String数组中的元素null
String数组中的元素null
String数组中的元素null
String数组中的元素null
String数组中的元素null
String数组中的元素null
String数组中的元素null
String数组中的元素null
*/
关于String[] args数组的练习
//模拟一个系统,假设这个系统要使用,必须输入用户名和密码
public class ArrayTest04 {
//用户名和密码输入到String[] args数组当中。
//怎么在idea中修改进入String[] args数组的数据呢?
//RUN-Edit Configurations-Program Argument进行设置
public static void main(String[] args) {
if (args.length != 2){
System.out.println("使用该系统请输入程序参数,包括用户名和密码,例如zhangsan 123");
return;
}
//判断用户名和密码是否正确
//取出用户名和密码
String username = args[0];
String password = args[1];
//假设用户名为admin密码为123的时候表示登录成功。
//判断两个字符串相等,需要使用equals方法。
// if (username.equals("admin") && password.equals("123")){
// System.out.println("登录成功,欢迎使用!");
// }else{
// System.out.println("请输入正确的用户名和密码");
// }
//代码存在空指针问题,需要进行优化
if ("admin".equals(admin) && "123".equals(password)){
System.out.println("登录成功,欢迎使用!");
}else{
System.out.println("请输入正确的用户名和密码");
}
}
}
数组的扩容和拷贝
数组满了,需要扩容。
java中对数组的扩容:先创建一个大容量的数组,然后将小容量数组中的数据一个一个拷贝到到数组当中。
结论:数组扩容效率很低,因为涉及到拷贝的问题。所以在以后的开发中请注意,尽可能少的进行数组的拷贝。可以在创建对象的时候预估一下多长合适,最好预估准确。可以减少数组的扩容次数,提高效率。
public class ArrayTest05 {
public static void main(String[] args) {
//java中数组怎么进行拷贝?
// System.arraycopy(5个参数);
//拷贝源(从这个数组中拷贝)
int[] src = {
1,11,22,3,4};
//拷贝目标(拷贝到这个目标数组上)
int[] dest = new int[20];//动态初始化一个长度为20的数组,默认值是0
//调用JDK System类中的arraycopy方法,完成数组的拷贝。
System.arraycopy(src,1,dest,3,2);
//遍历目标数组
for (int i = 0;i < dest.length;i++){
System.out.println(dest[i]);//0 0 0 11 22 后面是0
}
//数组中储存元素是引用,怎么拷贝?
String[] strs = {
"hello","world","study","java","oracle","mysql","jbdc"};
String[] newStrs = new String[20];
System.arraycopy(strs,0,newStrs,0,strs.length);
for (int i = 0;i<newStrs.length;i++){
System.out.println(newStrs[i]);
}
}
}