Chapter-Three数组
1、数组的概述
2、一维数组的使用
①一维数组的声明
②一维数组的初始化
数组声明中的[]既可以在变量前也可以在变量后即:int[] arr=new int[2]和int arr[]=new int[2]都是正确的
③数组元素的引用
④数组元素的默认初始化值
⑤代码演示一:使用方式
/*
* 一、
* 1.数组的概念:数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,
* 并通过编号的方式对这些数据进行统一管理。
* 2.数组相关的概念
* >数组名
* >元素
* >角标、下标、索引
* >数组的长度:元素的个数
*
* 3.数组的特点:
* 1)数组是有序排列的
* 2)数组属于引用数据类型的变量。数组的元素,既可以是基本数据类型,也可以是引用数据类型
* 3)创建数组对象会在内存中开辟一整块连续的空间
* 4)数组的长度一旦确定,就不能修改。
*
* 4.数组的分类:
* ①按照维数:一维数组、二维数组。。。
* ②按照数组元素的类型:基本数据类型元素的数组、引用数据类型元素的数组
*
* 5.一维数组的使用
* ①一维数组的声明和初始化
* ②如何调用数组的指定位置的元素
* ③如何获取数组的长度
* ④如何遍历数组
* ⑤数组元素的默认初始化值:见ArrayTest1.java
* ⑥数组的内存解析:见ArrayTest1.java
*/
public class ArrayTestFirst {
public static void main(String[] args) {
//1.一维数组的声明和初始化
int num;//声明
num=10;//初始化
int id=1001;//声明+初始化
int[] ids;//声明
//1.1静态初始化:数组的初始化和数组元素的赋值操作同时进行
ids=new int[]{1001,1002,1003,1004};
//1.2动态初始化:数组的初始化和数组元素的赋值操作分开进行
String[] names=new String[5];
//错误写法
// int[] arr1=new int[];
// int[5] arr2=new int[5];
// int[] arr3=new int[3]{1,2,3};
//也是正确的写法
int[]arr4={1,2,3,4,5};//类型判断
//总结:数组一旦初始化完成,其长度就确定了。
//2.如何调用数组的指定位置的元素:通过角标的方式调用。
//数组的角标(或索引)从0开始的,到数组的长度-1结束。
names[0]="王明";
names[1]="刘瘦瘦";
names[2]="刘十三";//charAt(0)
//3.如何获取数组的长度
//属性:length
System.out.println(names.length);
System.out.println(ids.length);
//4.如何遍历数组
System.out.println(names[0]);
System.out.println(names[1]);
System.out.println(names[2]);
for(int i=0;i<names.length;i++){
System.out.println(names[i]);
}
}
}
⑥代码演示二:数组初始值测试
package com.liuyongbin.one;
/**
* ⑤数组元素的默认初始化值
* >数组元素时整型:0
* >数组元素是浮点型:0.0
* >数组元素是char型:0或'\u0000',而非'0'
* >数组元素是boolean型(在底层都是二进制,false其实底层就是0,true是1):false
* >数组元素是引用数据类型:null
*/
public class ArrayTestDefaultValue {
public static void main(String[] args) {
//5.数组元素的默认初始化值
int[] arr=new int[4];
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
System.out.println("**********");
short[] arr1 = new short[4];
for(int i = 0;i < arr1.length;i++){
System.out.println(arr1[i]);
}
System.out.println("**********");
float[] arr2 = new float[5];
for(int i = 0;i < arr2.length;i++){
System.out.println(arr2[i]);
}
System.out.println("**********");
char[] arr3 = new char[4];
for(int i = 0;i < arr3.length;i++){
System.out.println("----" + arr3[i] + "****");
}
if(arr3[0] == 0){
System.out.println("你好!");
}
System.out.println("**********");
boolean[] arr4 = new boolean[5];
System.out.println(arr4[0]);
System.out.println("**********");
String[] arr5 = new String[5];
System.out.println(arr5[0]);
if(arr5[0] == null){
System.out.println("北京天气不错!");
}
long[] arr6=new long[3];
for(int i=0;i<arr6.length;i++){
System.out.println(arr6[i]);
}
//int num=arr6[0]+5;//错误:不能用int进行接收说明这个0是0L即long型的
}
}
⑦内存的简化结构
⑧一维数组的内存解析
在方法中声明的变量(局部变量)都是在栈中分配内存的。当执行到int[] arr1 = new int[4];时,首先会在栈中为arr1分配内存,执行到new时,会在堆中(引用数据类型的变量都是在堆中进行分配内存的)连续的地址进行创建可以存储4个整形变量大小的空间,而把该连续内存空间的首地址(16进制的地址)存储在arr1变量所对应的内存中。然后执行 arr1[0]=10;arr1[1]=20;在对应位置进行赋值操作。
String[] arr2 = new String[3];同样会在堆中分配可以存储三个字符串大小的内存空间并把首地址存储在arr2中;arr2[1] = “刘杰”;执行赋值操作;arr2 = new String[5];执行到new时又会在堆中分配可以存储5个字符串大小的内存空间,并把首地址给了arr2变量进行保存,此时arr2第一次保存的首地址被覆盖。第一个在堆中分配的数组由于没有被引用,在不确定的时间内会被垃圾回收机制进行回收,当整个方法执行完毕,所有栈中的变量出栈(可以理解为被销毁)则在堆中的引用也就不在了,在不确定的时间内会被垃圾回收机制进行回收。
3、多维数组的使用
①多维数组的使用
②二维数组的声明、初始化、调用指定位置元素、获取数组长度以及遍历
/*
* 1.理解
* 对于二维数组的理解,我们可以看成是一维数组
array1又作为另一个一维数组array2的元素而存
在。其实,从数组底层的运行机制来看,其实没
有多维数组。
2、二维数组的使用:
①二维数组的声明和初始化
②如何调用数组的指定位置的元素
③如何获取数组的长度
④如何遍历数组
⑤数组元素的默认初始化值 见TwoDimensionalArray02.java
⑥数组的内存解析 见TwoDimensionalArray02.java
*/
public class TwoDimensionalArray01 {
public static void main(String[] args) {
//1.二维数组的声明和初始化
int[] arr= new int[]{1,2,3,4,5};//一维数组
//静态初始化
int[][] arr1=new int[][]{{1,2,3},{1,4,5}};
//动态初始化1
String[][] arr2=new String[3][2];
//动态初始化2
String[][] arr3=new String[3][];
//正确但是非标准写法
int[] arr4[]=new int[][]{{1,2,3},{1,4,5,89,7}};
int arr5[][] =new int[][]{{1,2,3},{1,4,5}};
int arr6[][] ={{1,2,3},{1,4,5}};
// //错误的情况
// String[][] arr4= new String[][4];
// String[4][2] arr5= new String[][];
// int [][] arr6=new int[4][3]{{1,2,4},{3,3,13}};
//2.如何调用数组的指定位置的元素
System.out.println(arr1[0][1]);//2
System.out.println(arr2[1][1]);//null
arr3[1]=new String[3];
System.out.println(arr3[1][2]);
//3.获取数组的长度
System.out.println(arr4.length);//2 其实arr4[]本身就是一维的,只不过每个元素里又保存了一个数组的首地址
System.out.println(arr4[0].length);//3
System.out.println(arr4[1].length);//5
//4.如何遍历二维数组
for(int i=0;i<arr4.length;i++){
for(int j=0;j<arr4[i].length;j++){
System.out.print(arr4[i][j]+" ");
}
System.out.println();
}
}
}
③二维数组的默认初始值
/*
* 二维数组的使用:
* 规定:二维数组分为外层数组的元素,内层数组的元素。
* int[] arr= new int[4][3];
* 外层元素:arr[0],arr[1]等
* 内层元素:arr[0][0],arr[1][2];
*
* ⑤数组元素的默认初始化值
* 针对初始化方式一:比如:int[][]arr=new int[4][3];
* 外层元素的初始化值为:地址值
* 内层元素的初始值为:与一维数组初始化情况相同
*
* 针对初始化方式二:比如:int[][]arr=new int[4][];
* 外层元素的初始值为null
* 内层元素的初始值为:不能调用,否则报错(空指针异常)
* ⑥数组的内存解析
*/
public class TwoDimensionalArray02 {
public static void main(String[] args) {
int arr[][] =new int[4][3];
System.out.println(arr[0]);//因为是二维数组,数组是引用类型,所以
//相当于一维里面报存的都是地址(不明白的话看后面的内存图解)
//该输出结果是:[I@15db9742 分析[:代表的是一维数组 I代表元素的类型 @后面是保存的地址值
System.out.println(arr[0][2]);//0
System.out.println(arr);//[[I@6d06d69c
//[[:代表是二维数组 I说明是int行 @后是地址
System.out.println("-------------");
float[][] arr1=new float[4][3];
System.out.println(arr1[0]);//[F@7852e922
System.out.println(arr1[2][1]);//0.0
System.out.println("-------------");
String arr2[][]=new String[4][2];
System.out.println(arr2[1]);//[Ljava.lang.String;@4e25154f
System.out.println(arr2[1][1]);//null
System.out.println("-------------");
double[][] arr3=new double[4][];
System.out.println(arr3[2]);//null
//System.out.println(arr3[3][1]);//空指针异常
}
}
④二维数组的内存分析
⑤练习题一
⑥练习题二
package com.liuyongbin.exer;
/*
* 使用简单数组
(1)创建一个名为ArrayExer2的类,在main()方法中声明array1和array2两个变量,他们是int[]类型的数组。
(2)使用大括号{},把array1初始化为8个素数:2,3,5,7,11,13,17,19。
(3)显示array1的内容。
(4)赋值array2变量等于array1,修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)。打印出array1。
*
* 思考:array1和array2是什么关系?array1和array2地址值相同,都指向了堆空间的唯一的一个数组实体。
* 拓展:修改题目,实现array2对array1数组的复制
*/
public class ArrayExer2 {
public static void main(String[] args) { //alt + /
int[] array1,array2;
array1 = new int[]{2,3,5,7,11,13,17,19};
//显示array1的内容
for(int i = 0;i < array1.length;i++){
System.out.print(array1[i] + "\t");
}
//赋值array2变量等于array1
//不能称作数组的复制。
array2 = array1;
//修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)
for(int i = 0;i < array2.length;i++){
if(i % 2 == 0){
array2[i] = i;
}
}
System.out.println();
//打印出array1
for(int i = 0;i < array1.length;i++){
System.out.print(array1[i] + "\t");
}
}
}
⑦练习题三
package com.liuyongbin.exer;
/*
* 使用简单数组
* 拓展:修改题目,实现array2对array1数组的复制
*/
public class ArrayExer3 {
public static void main(String[] args) { //alt + /
int[] array1,array2;
array1 = new int[]{2,3,5,7,11,13,17,19};
//显示array1的内容
for(int i = 0;i < array1.length;i++){
System.out.print(array1[i] + "\t");
}
//数组的复制:
array2 = new int[array1.length];
for(int i = 0;i < array2.length;i++){
array2[i] = array1[i];
}
//修改array2中的偶索引元素,使其等于索引值(如array[0]=0,array[2]=2)
for(int i = 0;i < array2.length;i++){
if(i % 2 == 0){
array2[i] = i;
}
}
System.out.println();
//打印出array1
for(int i = 0;i < array1.length;i++){
System.out.print(array1[i] + "\t");
}
}
}
4、数组中涉及到的常见算法
①冒泡排序
package com.liuyongbin.one;
/*
* 冒泡排序的实现
*/
public class BubbleSort {
public static void main(String[] args) {
//冒泡排序的实现一
int[] arr={1,60,7,8,9,45,3,36,89,0,3,100,16,78,30};
for(int i=arr.length;i>1;i--){
for(int j=1;j<i;j++){
if(arr[j]<arr[j-1]){
int temp=arr[j];
arr[j]=arr[j-1];
arr[j-1]=temp;
}
}
System.out.print(arr[i-1]+" ");
}
System.out.println();
//实现方式二
for(int i=0;i<arr.length-1;i++){
for(int j=0;j<arr.length-1-i;j++){
if(arr[j+1]<arr[j]){
int temp=arr[j];
arr[j]=arr[j-1];
arr[j-1]=temp;
}
}
System.out.print(arr[arr.length-1-i]+" ");
}
}
}
4、 Arrays工具类的使用
package com.liuyongbin.one;
import java.util.Arrays;
/*
* java.util.Arrays:操作数组的工具类,里面定义了很多操作数组的方法
* 操作数组时,可以先去查看api文档
*/
public class ArraysTest {
public static void main(String[] args) {
//1.boolean equals(int[] a,int[] b):判断两个数组是否相等。
int arr1[]=new int[]{1,2,3,4};
int arr2[]=new int[]{1,3,2,4};
boolean isEquals=Arrays.equals(arr1, arr2);
System.out.println(isEquals);//false
//2.String toString(int[] a):输出数组信息。
String result1=Arrays.toString(arr1);
System.out.println(Arrays.toString(arr2));//[1, 3, 2, 4]
System.out.println(result1);//[1, 2, 3, 4]
//3.void fill(int[] a,int val):将指定值填充到数组之中。
Arrays.fill(arr1, 2);
System.out.println(Arrays.toString(arr1));//[2, 2, 2, 2]
//4.void sort(int[] a):对数组进行排序。
Arrays.sort(arr2);
System.out.println(Arrays.toString(arr2));//[1, 2, 3, 4]
//5.int binarySearch(int[] a,int key):查找元素所在位置,如果不存在则返回一个负数(可以查看源码)
Arrays.sort(arr2);
System.out.println(Arrays.binarySearch(arr2, 3));
}
}
5、数组中的常见异常
package com.liuyongbin.one;
/*
* 数组中常见异常
* 1.数组角标越界的异常:ArrayIndexOutOfBoundsException
*
* 2.空指针异常:NullPointerException
*/
public class ArrayException {
public static void main(String[] args) {
//1.数组角标越界的异常:ArrayIndexOutOfBoundsException
int[] arr=new int[]{1,2,3,4};
// for(int i=0;i<=arr.length;i++){
// System.out.println(arr[i]);
// }
//2.空指针异常:NullPointerException
//情况一
// int[] arr1=new int[]{1,2,3,4};
// arr1=null;
// System.out.println(arr1[0]);
//情况二
int[][] arr2=new int[4][];
System.out.println(arr2[0][0]);
//情况三
// String[] arr3=new String[]{"AA","BB","ccc","ddd"};
// arr3[0]=null;
// System.out.println(arr3[0].toString());
}
}