数组是存储同一种数据类型多个元素的集合。也可以看成是一个容器。数组既可以存储基本数据类型,也可以存储引用数据类型,注意数组必须将进行初始化,初始化之后才能使用。所谓的初始化就是在内存中为数组开辟一块空间,并为数组的元素赋其默认值
一个数组的举例:
int [] arr={10,30,50,70,90} ;
对于上面的数组代码:
数组arr为整型数组,即数组arr中只能存放整型的数组元素
其次在arr数组中该数组的第一个元素是arr[0],其值是10,最后一个元素是arr[4],其值是90
数组arr的长度是5
数组的特点说明 |
---|
数组的长度一旦确定就不能修改 |
创建数组对象会在内存中开辟一整块连续的空间。而数组名中引用的是这块连续空间的首地址 |
遍历数组和获取某个元素的速度快,因为可以通过数组名+下标,直接定位到任意一个元素 |
数组既可以存储基本数据类型,也可以存储引用数据类型 |
//数组存储基本数据类型:
int[] a = {80,90,100,110,120};
a数组的类型是:int[]
元素的类型是int
//数组存储引用数据类型:
String[] strings = {“hello”,”java”};
strings数组的类型是:String[]
元素的类型是String
数组的分类 | 分类的结果 |
---|---|
按照维度 | 一维数组、二维数组、多维数组 |
按照元素的数据类型 | 基本数据类型元素的数据,引用数据类型元素的数组 |
Java中的数组必须先初始化,然后才能使用,所谓初始化:就是为数组中的数组元素分配内存空间,并为每个数组元素赋值
对于一维数组的初始化有动态初始化和静态初始化两种方法,对于这两种方法,各有特点:
具体定义格式:
数据类型[] 数组名 = new 数据类型[数组长度];
数组长度其实就是数组中元素的个数
举例: int[] arr = new int[3]; 定义了一个int类型的数组arr,这个数组可以存放3个int类型的值。
对于上面的具体格式有两种表现格式:
格式1: 数据类型[] 数组名;
格式2: 数据类型 数组名[];
两种格式中实际上更推荐使用第一种定义方式,比较清晰便捷
接下来的数组动初始化实例将结合java程序在计算机内存进行说明,请先跳转至“三.Java中的内存分配以及堆栈的理解”进行阅读
下面是关于动态初始化的代码实例:
[1] 关于一个一维数组的动态初始化:
class ArrayTest{
public static void main(String[] args) {
int[] arr=new int[3];
System.out.println(arr); //打印数组的地址值
arr[0]=10;
arr[1]=20;
arr[2]=30;
System.out.println(arr[0]);
}
}
[2] 关于两个一维数组的动态初始化:
class ArrayTest2 {
public static void main(String[] args) {
int[] arr=new int[3];
arr[0]=10;
arr[1]=20;
arr[2]=30;
int[] arr2=new int[2];
arr2[0]=100;
arr2[1]=200;
//输出数组的地址值
System.out.println(arr);
System.out.println(arr2);
//输出数组中的元素
System.out.println(arr[2]);
System.out.println(arr2[0]);
}
}
[3] 关于三个一维数组的动态初始化:(其中包含数组的引用)
class ArrayTest3{
public static void main(String[] args) {
int[] arr1=new int[2];
arr1[0]=15;
arr1[1]=20;
int[] arr2=new int[2];
arr2[0]=33;
arr2[1]=89;
int[] arr3=arr1;
arr3[0]=500;
//输出数组的地址值
System.out.println(arr1);
System.out.println(arr2);
System.out.println(arr3);
//判断两个数组的地址值是否相等
System.out.println(arr1==arr3);
//输出数组中的元素
System.out.println(arr1[0]);
System.out.println(arr1[1]);
System.out.println(arr2[0]);
System.out.println(arr2[1]);
System.out.println(arr3[0]);
System.out.println(arr3[1]);
}
}
静态初始化的格式:
格式:数据类型[] 数组名 = new 数据类型[]{元素1,元素2,…};
举例: int[] arr = new int[]{1,2,3};
简化格式:
数据类型[] 数组名 = {元素1,元素2,…};
举例: int[] arr = {1,2,3};
关于静态初始化数组的相关代码以及内存图解:
class ArrayDemo5{
public static void main(String[] args) {
//数组的静态初始化:由我们为数组元素赋值,由系统计算长度
int[] arr=new int[]{20,30,50,60};
arr[0]=30;
//静态初始化的简写方式,省略new那部分不写
double[] arr2={3.14,5.8,68,3.9};
System.out.println(arr[0]);
System.out.println(arr2[0]);
}
}
首先需要介绍的是java虚拟机的内存分布图:
然后是着重对于堆内存和栈内存的比较:
堆和栈存放变量的区别和说明 |
---|
栈:存放的局部变量。所谓局部变量是在方法中定义或者在方法声明上的变量 |
堆:存放的是所有new出来的对象(数组也是对象) |
最后是对于整个java虚拟机中的各个部分的详细介绍:
出现原因: 在获取数组元素或者给数组元素赋值访问了不存在的索引,就会出现数组角标越界
代码演示:
public class test {
public static void main(String[] args) {
int[] arr={10,20,30,40,50,60,70,80,90};
for(int i=0;i<10;i++){
System.out.println(arr[i]);
}
}
}
出现原因: 在使用空数组进行方法操作时,传参传空参数等等都会造成这种异常
代码演示:
public class test {
public static void main(String[] args) {
String a=null;
int x=a.length;
System.out.println(x);
}
}
}
正序遍历:
package zjl.westos.nwpu;
//遍历数组中的所有元素,使用下标遍历法:
public class ArrFind {
public static void main(String[] args){
int[] arr={0,1,2,3,4};
for(int j=0;j<arr.length;j++){
System.out.print(arr[j]+" ");
}
}
}
package zjl.westos.nwpu;
public class ArrFindInReverse {
public static void main(String[] args){
int[] array={20,30,40,50,60};
for(int i=array.length-1;i>=0;i--){
System.out.println(array[i]);
}
}
}
package zjl.westos.nwpu;
public class ArrFindMaxAndMin {
public static void main(String[] args) {
int[] array = {20, 30, 40, 50, 60, 70, 80};
int emax = 0;
int emin = 1000000;
for (int elem : array) {
if (elem > emax) emax = elem;
}
System.out.println("Array中的最大值是:" + emax);
for (int elem : array) {
if (elem < emin) emin = elem;
}
System.out.println("Array中的最小值是:" + emin);
}
}
package zjl.westos.nwpu;
public class ArrReverse {
public static void main(String[] args){
int[] arr={10,20,30,40,50,60};
int i,j;
for (i=0,j=arr.length-1;i<j;i++,j--){
int t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
for (int i1 = 0; i1 < arr.length; i1++) {
System.out.print(arr[i1]+" ");
}
}
}
package zjl.westos.nwpu;
public class ArrSumAndAverage {
public static void main(String[] args) {
int[] arr={10,20,30,40,50,60,70,80};
int sum=0;
double average;
for (int i = 0; i < arr.length; i++) {
sum+=arr[i];
}
average = sum*1.0/arr.length;
System.out.println("数组中的值总和是:"+sum);
System.out.println("数组中元素的平均值是:"+average);
}
}
我将两个算法的代码融入了一个程序:
package zjl.westos.nwpu;
import java.util.Scanner;
public class Week {
public static void main(String[] args) {
String[] week = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期七", "星期二"};
Scanner input = new Scanner(System.in);
System.out.println("请输入需要寻找的角标对应的元素:");
int index_find = input.nextInt();
String x = getElemFromIndex(week, index_find);
System.out.println("对应角标的元素是:" + x);
System.out.println("请输入需要寻找的元素及其对应的位置:输入内容是星期一至七");
String s = input.next();
getIndexFromElem(week, s);
}
public static String getElemFromIndex(String[] arr, int t) {
return arr[t];
}
public static void getIndexFromElem(String[] arr, String t) {
int []elem=new int[arr.length];
int flag = 0;
for (int i = 0; i < arr.length; i++) {
if (t.equals(arr[i])) {
elem[flag] = i;
flag++;
}
}
System.out.print("共出现了"+flag+"次,位置分别是:");
if(elem[0]==0&&flag!=0){
System.out.print(elem[0]+" ");
}
else if(elem[0]!=0){
System.out.print(elem[0]+" ");
}
for(int i=1;i< elem.length;i++){
if(elem[i]!=0){
System.out.print(elem[i]+" ");
}
else break;
}
}
}
注意:
(1) String类型的元素在比较时不能使用==,使用==比较的是两个字符串所指向的地址,而使用s1.equals(s2)才比较的是字符串s1和s2的字面值是否相等
(2) 函数getIndexFromElem中的循环体意义在于将出现次数不止一次的元素记录下来并输出