java基础-引用数据类型之一维数组(Array)
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.数组的定义
1>.为什么需要数组
保存一个数据可以定义一个变量,如果要保存一个班级的100多名同学的成绩,是否要定义100多个变量呢?其实在Java中可以通过定义一个变量来保存这100多个同学的成绩,而保存这么100多个学生成绩的载体就是数组。
2>.数组的概念
数组是同一种数据类型的集合,可以是基本数据类型,也可以是引用数据类型。变量就是内存中的一块存储空间,数据就是内存中的一块连续的存储空间。
3>.数组的特点
a>.数组存储的都是相同数据类型的元素;
b>.数组的长度也就是数组中元素的个数;
c>.元素从0开始编号,编号也称“索引”:index(下标,角标);
d>.数组中元素的访问方式是通过“数组名+索引”的方式;
4>.数组的声明
5>.数组的初始化
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ public class ArrayDemo{
/*
数组:
同一种数据类型的若干个值的容器.
元素:
数组中的值称为元素.
索引:
元素的标号,从0开始.
长度:
数组中元素的个数. */
public static void main(String[] args){
//定义数组,第一种格式:动态初始化,定义数组时,不指定数组里具体的值.
int[] arr = new int[10];
/**
arr是数组名称,arr的数据类型是int[],new int[10]会在内存中分配
一块连续的存储空间,这块存储空间可以存储10个int类型的元素。在定义数
组时,括号也可以卸载数组名的后面,如“int arr[] = new int[10];”,
但是我不建议这样写!
*/ //第二种静态初始化:定义数组时,元素已经确定.
int[] arr2 = new int[]{1,2,3}; //简化写法,在定义元素的同时,可以给数组的各个元素进行赋值。
int[] arr3 = {10,20,30};
/**
定义了一个数组arr3,这个数组的每个元素是10,20,30.这个数组的长度
就是初始化时制定的数组元素的个数。
*/ }
}
二.数组的内存结构
数组是引用数据类型,那么大家知道引用数据类型和基本数据的类型的区别吗?其实,(操作系统给JVM分配一块连续的内存地址)Java程序在运行时,为了提高运行效率,对内存进行了不同区域的划分,每一种区域都有特定的处理数据的方式和内存管理方式,主要有一下几种
各个内存区域的特点如下:
a>.栈内存:所有的方法运行的时候交进入的内存,用于存储局部变量,当数据使用完,所占空间会自动释放;
b>.堆内存:存放数据和对象(存储的是容器和对象),通过new建立的实例都存放在堆内存中,每一个实例都有内存地址值,实例中的变量都有默认初始化值,当实例不在被使用,会在不确定的时间被垃圾回收器回收;
c>.方法区:存放类文件和方法(这里暂时先卖个关子,等到面向对象部分在给大家详细分析,数组的存储跟方法区关系不大);
d>.本地方法栈:供本地方法使用,与操作系统相关(有时候Java有些功能自己不能单独完成,比如复制,粘贴就可以调用操作系统的模块);
e>.程序计数器(英文:Program Counter):对字节码文件计数;
如上图所述,当我们执行“int[] arr = new int[4];”,可以很明显的看出来会在堆内存中创建一块单独的连续的内存空间并给这个连续的内存空间中的每一个元素赋初始值(int[]类型默认为0),然后再讲这个数组中的首个元素的下标的内存地址赋值给栈内存。也就是说“int[] arr = new int[4];”中的arr实际存储的是arr的在堆内存中的内存地址,并不是具体的数值。而“arr[3]=10;”是找到arr数组中对应的第四个元素(数组的默认其实下标为0)并将其值修改为10.
三.数组元素的访问
我们可以通过索引值(下标值)来访问数组的各个元素。不过要注意的是,下标的起始位置是“0”。
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ public class ArrayDemo1{
/*
数组的访问方式:
数组名[索引值]
*/
public static void main(String[] args){
//创建一个长度为10的String类型的数组
String[] arr = new String[5]; //访问arr数组的第一个元素并将结果赋值给一个变量字符串变量。
String Name = arr[0]; //修改第一个元素的值。
arr[0] = "yinzhengjie"; //访问arr数组的内存地址
System.out.println(arr); //访问arr的全部元素
for(int i=0;i< arr.length;i++){
System.out.println(arr[i]);
}
/**
定义了数组之后,系统会给数组的各个元素进行默认的初始化操作
a>.对于数值型数据默认初始化为0;
b>.对于布尔数据默认初始化为false;
c>.对于字符数据默认初始化为码值为0的字符;
d>.对于引用数据类型默认初始化为null;
*/ int[] arr1 = new int[3];
arr1[2] = 2018;
int i = 0;
while(true){
if(i < arr1.length){
System.out.println(arr1[i]);
}else{
break;
}
i++;
} System.out.println("-------------------");
String[] arr2={"尹","正","杰"};
//如果遍历某个集合中所有的数据,还可以使用foreach循环
for(String x:arr2){
System.out.println(x);
}
/**
依次把arr2数组的每一个元素赋值x变量,在循环体中可以对x变量进行处理。
*/ }
}
四.数组定义常见问题
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ public class ExceptionDemo{
public static void main(String[] args){
/*
数组操作的常见异常
1.数组索引越界
2.空指针异常
3.数据类型不匹配
*/ int[] arr = new int[]{1,2,3,4,5,6};
int[] arr2 = new int[]{7,8,9};
int[] arr3 = new int[]{70,80,90};
boolean[] arr4 = {true,false,true,true}; printArray(arr);
printArray(arr2);
printArray(arr3);
printArray(arr4); // System.out.println(arr[30]);
/**类型一:
“java.lang.ArrayIndexOutOfBoundsException:数组索引越界异常”。
原因:
访问到了数据中不存在的索引发生的异常。
*/ // arr = null;
// System.out.println(arr[2]);
/**
类型二:
“java.lang.NullPointerException:空指针异常”
原因:
arr引用没有指向数组,却在操作数组中的元素。
*/ //arr = "yinzhengjie";
/**
类型三:“错误: 不兼容的类型: String无法转换为int[]”
原因:
我们上面另一的arr类型为int[],而我们传入的确实一个字符串类型!
*/ } public static void printArray(int[] arr){
for(int i = 0;i<arr.length;i++){ //根据数组的length属性动态的获取数组的长度
System.out.print(arr[i] + " ");
}
System.out.println();
} public static void printArray(boolean[] arr){
for(int i = 0;i<arr.length;i++){
System.out.print(arr[i] + " ");
}
System.out.println();
}
}
五.小试牛刀
1>.随机生成一个数字,并自动求出其中的最大值和最小值。
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ import java.util.Scanner; public class ArraryDemo2{
//获取数组
public static int[] getArray(){
Scanner s = new Scanner(System.in);
System.out.print("请输入数组的长度:>>>");
int len = s.nextInt();
int[] arr = new int[len] ;
for(int i = 0;i<len;i++){
System.out.print("请输入第" + (i+1) + "个数:>>>");
int number = s.nextInt();
arr[i] = number;
}
return arr;
} //获取最大值
public static int getMax(int[] arr){
int max = arr[0];
for(int i = 0;i < arr.length;i++){
if(arr[i] > max){
max = arr[i];
}
}
return max;
} //获取最小值
public static int getMin(int[] arr){
int min = arr[0];
for(int i = 0;i<arr.length;i++){
if(arr[i] < min){
min = arr[i];
}
}
return min;
} public static void main(String[] args){
int[] arr = getArray();
System.out.println("最大值是:" + getMax(arr));
System.out.println("最小值是:" + getMin(arr));
} }
2>.每位数字都加上8,然后用和除以10的余数代替该数字,再将生成的数字反转。
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ import java.util.Scanner; /*
某个公司采用公用电话传递数据,数据是随机的整数(整数的个数由用户自定义),
在传递过程中是加密的,加密规则如下:每位数字都加上8,然后用和除以10的余数
代替该数字,再将生成的数字第一位和最后以为互换一下顺序,第二位和倒数第二位
互换一下顺序,以此类推...。
*/ public class DataEncryption{
//主函数
public static void main(String[] args){
int[] array = randomArray(); //获取随机数组
encryptionArray(array); //加密操作
ArraySwap(array); //将加密的数字进行反转
System.out.print("加密后的数字是:"+"\t");
printArray(array); decryptArray(array); //解密操作
ArraySwap(array); //然后在将数据反转 System.out.print("解密后的数字是:"+"\t");
printArray(array);
}
//随机生成一个数组
public static int[] randomArray(){
Scanner Input = new Scanner(System.in);
System.out.print("请输入您想产生随机数的个数:>>> ");
int number = Input.nextInt();
int[] array = new int[number];
for(int index=0;index<array.length;index++){
array[index] = (int)(Math.random()* 8 + 1); //表示随机生成一个int类型的数字并赋值。
}
System.out.print("您产生的随机数是:" + "\t");
printArray(array);
return array;
}
//加密方法:每个数字都加上8之后除以10的余数来代替该数字.
public static void encryptionArray(int[] args){
for(int index = 0;index < args.length;index++){
args[index]= (args[index] + 8)%10;
}
}
//解密方法:每个数字都加上2之后除以10的余数来代替该数字.
public static void decryptArray(int[] args){
for(int index = 0;index < args.length;index++){
args[index]= (args[index] + 2)%10;
}
} //将数组翻转
public static void ArraySwap(int[] args){
for(int index=0;index<=args.length/2;index++){
int temp = args[index];
args[index] = args[args.length-1-index];
args[args.length-1-index] = temp;
}
}
//遍历数组
public static void printArray(int[] args){
for(int index=0;index<args.length;index++){
System.out.print(args[index] + " ");
}
System.out.println();
}
}
六.Java参数传递问题-值传递
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ public class CopyArrayDemo{
/*
数组的复制:返回值类型是数组
判断堆空间中的两个对象(数组)是否是同一个数组,可以使用 == 判断他们的地址值
*/
public static void main(String[] args){
int[] arr1 = genArray();
System.out.println("arr1的内存地址是:" + arr1);
print(arr1);
int[] arr2 = copyArray(arr1);
// int[] arr2 = arr1; //arr2引用的是arr1同一块内存地址
print(arr2); // System.out.println(arr1 == arr2);//
System.out.println("arr2的内存地址是:" + arr2);//[I@6d06d69c 类型@十六进制值 } //定义获取一个数组的方法
public static int[] genArray(){
int[] arr = new int[5];
for(int i = 0;i<arr.length;i++){ //这里是利用的数组的length属性,可以获取数组的长度。
int r = (int)(Math.random() * 50 + 1); //这里是利用了Java内置的模块模拟了的随机生成1-50的int数字
arr[i] = r;
}
return arr;
} //我这里专门定义了一个可以打印数组的犯法
public static void print(int[] arr){
for(int i = 0;i<arr.length;i++){
System.out.print(arr[i] + " ");
}
System.out.println();
} //这里是用于拷贝数组的方法
public static int[] copyArray(int[] arr){
//1>.创建一个和参数一样大小的数组
int[] copy = new int[arr.length];
//2>.遍历参数的数组,把元素拷贝到新数组中
for(int i = 0;i<arr.length;i++){
copy[i] = arr[i];
}
//3>.将拷贝元数组的副本返回
return copy;
}
}