数组:数组是存储同一种数据类型数据的集合容器。
数组的定义格式:
数据类型[] 变量名 = new 数据类型[长度];
分析数组:
左边: int[] arr 声明了一个int类型的的数组变量,变量名为arr。
int : 表示该数组容器只能存储int类型的数据。
[] : 这是一个数组类型。
arr : 变量名.
右边:new int[50]; 创建了一个长度为50的int类型数组对象。
new : 创建数组对象的关键字。
int: 表示该数组对象只能存储int类型数据。
[]: 表示是数组类型。
50 : 该数组最多能存储50个数据。数组的容量。
数组的好处: 对分配到数组对象中每一个数据都分配一个编号(索引值、角标、下标),索引值的范围是从0开始,最大是: 长度-1.
局部变量: 如果一个变量是在一个方法(函数)的内部声明的,那么该变量就是一个局部变量。
成员变量: 成员变量就是定义在方法之外,类之内的.
下边举个栗子
class Demo1
{
public static void main(String[] args)
{
//定义一个数组
int[] arr = new int[4];
arr[0] = 10;
arr[1] = 30;
arr[2] = 50;
arr[3] = 90;
//System.out.println("数组的容量:"+ arr.length); //数组的有一个length 的属性,可以查看数组 的容量。
//System.out.println("arr[2] = "+ arr[2]);
//查看数组中的所有数据。
for(int index = 0 ; index<arr.length ; index++){
System.out.println(arr[index]);
}
}
}
1、数组的定义
格式1: |
元素类型[] 数组名 = new 元素类型[元素个数或数组长度]; 示例:int[] arr = new int[5]; |
格式2: |
元素类型[] 数组名 = new 元素类型[]{元素,元素,……}; int[] arr = new int[]{3,5,1,7}; int[] arr = {3,5,1,7}; |
注意:给数组分配空间时,必须指定数组能够存储的元素个数来确定数组大小。创建数组之后不能修改数组的大小。可以使用length 属性获取数组的大小。
遍历数组
2、数组初始化
数组的格式
int[] x = new int[3]; x[0] = 1; x[1] = 2; |
另一种定义:该形式可以直接明确数组的长度,以及数组中元素的内容
int[] x = { 1, 2, 3 }; |
int[] x=new int[]{1,2,3}; |
初始化方式1:不使用运算符new int[] arr = { 1, 2, 3, 4, 5 }; int[] arr2 = new int[] { 1, 2, 3, 4, 5 }; 初始化方式2: int[] arr3=new int[3]; arr3[0]=1; arr3[1]=5; arr3[2]=6;
|
如果数组初始化中不使用运算符new。需要注意:下列写法是错误的。
int[] arr; arr={1,2,3,4,5}; |
此时初始化数组,必须将声明,创建,初始化都放在一条语句中个,分开会产生语法错误。
所以只能如下写:
int[] arr={1,2,3,4,5}; |
举个例子:
/*
数组的初始化方式:
动态初始化:
数据类型[] 变量名 = new 数据类型[长度];
静态初始化:
数据类型[] 变量名 = {元素1,元素2.....};
如果程序一开始你就已经确定了数据,那么这时候建议使用静态初始化。如果
数据一开始还不太明确,这时候就建议使用动态初始化。
*/
class Demo
{
public static void main(String[] args)
{
//动态初始化
//int[] arr = new int[10];
//静态初始化
int[] arr = {10,20,30,40,50};
for(int index = 0 ; index<arr.length ; index++){
System.out.print(arr[index]+",");
}
/*
int[] arr = new int[50];
Scanner scanner = new Scanner(System.in);
for(int i = 0 ; i< arr.length ; i++){
arr[i] = scanner.nextInt();
}
*/
}
}
3、数组遍历
public static void main(String[] args) { int[] x = { 1, 2, 3 }; for (int y = 0; y < 3; y++) { System.out.println(x[y]); // System.out.println("x["+y+"]="+x[y]); 打印效果 x[0]=1; } // 那么这就是数组的第一个常见操作.遍历 } |
数组中有一个属性可以获取到数组中元素的个数,也就是数组的长度. 数组名.length
public static void main(String[] args) { int[] x = { 1, 2, 3 }; for (int y = 0; y < x.length; y++) { System.out.println(x[y]); // System.out.println("x["+y+"]="+x[y]); 打印效果 x[0]=1; } // 那么这就是数组的第一个常见操作.遍历 } |
4、数组的常见异常
(1)数组角标越界异常:,注意:数组的角标从0开始。
public static void main(String[] args) { int[] x = { 1, 2, 3 }; System.out.println(x[3]); //java.lang.ArrayIndexOutOfBoundsException } |
(2)空指针异常:
public static void main(String[] args) { int[] x = { 1, 2, 3 }; x = null; System.out.println(x[1]); // java.lang.NullPointerException } |
举个栗子:
/*
数组中最常见的问题:
1. NullPointerException 空指针异常
原因: 引用类型变量没有指向任何对象,而访问了对象的属性或者是调用了对象的方法。\
2. ArrayIndexOutOfBoundsException 索引值越界。
原因:访问了不存在的索引值。
*/
class Demo2
{
public static void main(String[] args)
{
/*
int[] arr = new int[2];
arr = null ; //null 让该变量不要引用任何的对象。 不要记录任何的内存地址。
arr[1] = 10;
System.out.println(arr[1]);
*/
int[] arr = new int[4];
arr[0] = 10;
arr[1] = 30;
arr[2] =40;
arr[3] = 50;
//System.out.println(arr[4]); //访问索引值为4的内存空间存储的值。
for(int index = 0 ; index<=arr.length ; index++){
System.out.print(arr[index]+",");
}
}
}
5、数组的内存分析
下边为一些具体应用:
案例1:最大值挑选
/*
需求: 定义一个函数接收一个int类型的数组对象,找出数组对象中 的最大元素返回给调用者。
*/
class Demo
{
public static void main(String[] args)
{
int[] arr = {-12,-14,-5,-26,-4};
int max = getMax(arr);
System.out.println("最大值:"+ max);
}
public static int getMax(int[] arr){
int max = arr[0]; //用于记录最大值
for(int i = 1 ; i < arr.length ; i++){
if(arr[i]>max){ //如果发现有元素比max大,那么max变量就记录该元素。
max = arr[i];
}
}
return max;
}
}
案例2: 直接排序
/*
需求: 定义一个函数接收一个int类型的数组对象, 把数组中的最大值放在数组中的第一位。
选择排序(直接排序):使用一个元素与其他 的元素挨个比较一次,符合条件交换位置。
*/
class Demo{
public static void main(String[] args)
{
int[] arr = {12,5,17,8,9}; //对于5元素的数组,只需要找出4个最大值就可以排序了。
selectSort(arr);
}
public static void selectSort(int[] arr){
//把最大值放在首位置。
for(int j = 0; j<arr.length-1; j++){ // 控制的是轮数。
for(int i = j+1 ; i<arr.length ; i++){ // 找出最大值
if(arr[i]>arr[j]){
//交换位置
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
/*
//把老二放在第二个位置
for(int i = 2 ; i< arr.length ; i++){
if(arr[i]>arr[1]){
int temp = arr[i];
arr[i] = arr[1];
arr[1] = temp;
}
}
//把老三放在第三个位置
for(int i = 3 ; i< arr.length ; i++){
if(arr[i]>arr[2]){
int temp = arr[i];
arr[i] = arr[2];
arr[2] = temp;
}
}
//把老四放在第四个位置
for(int i = 4 ; i< arr.length ; i++){
if(arr[i]>arr[3]){
int temp = arr[i];
arr[i] = arr[3];
arr[3] = temp;
}
}
*/
//遍历数组,查看效果
System.out.print("目前的元素:");
for (int i = 0 ; i<arr.length ;i++){
System.out.print(arr[i]+",");
}
}
}
案例3:冒泡排序
/*
需求: 定义一个函数接收一个int类型的数组对象, 把数组中的最大值放在数组中的最后一位。
冒泡排序:冒泡排序的思想就是使用相邻的两个 元素挨个比较一次,符合条件交换位置。
*/
class Demo10
{
public static void main(String[] args)
{
int[] arr = {12,8,17,5,9}; // 最大的索引值: 4 容量:5
bubbleSort(arr);
}
public static void bubbleSort(int[] arr){
// 把最大值放在最后一个位置
for(int j = 0 ; j<arr.length-1 ; j++){ //控制轮数
for(int i = 0 ; i<arr.length-1-j ; i++){ // 找出一个最大值
//相邻的元素比较
if(arr[i]>arr[i+1]){
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
}
/*
//把老二放在倒数第二个位置上。
for(int i = 0 ; i <arr.length-1-1 ; i++){
if(arr[i]>arr[i+1]){
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
//把老三放在倒数第三个位置上。
for(int i = 0 ; i <arr.length-1-2 ; i++){
if(arr[i]>arr[i+1]){
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
//把老四放在倒数第四个位置上。
for(int i = 0 ; i <arr.length-1-3 ; i++){
if(arr[i]>arr[i+1]){
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
*/
//遍历数组,查看效果
System.out.print("目前的元素:");
for (int i = 0 ; i<arr.length ;i++){
System.out.print(arr[i]+",");
}
}
}
案例4:二分法
/*
需求:定义一个函数接收一个数组对象和一个要查找的目标元素,函数要返回该目标元素在
数组中的索引值,如果目标元素不存在数组中,那么返回-1表示。
折半查找法(二分法): 使用前提必需是有序的数组。
*/
class Demo12
{
public static void main(String[] args)
{
int[] arr = {12,16,19,23,54};
//int index = searchEle(arr,23);
int index = halfSearch(arr,116);
System.out.println("元素所在的索引值是:"+ index);
}
public static int halfSearch(int[] arr, int target){
//定义三个变量分别记录最大、最小、中间的查找范围索引值
int max = arr.length-1;
int min = 0;
int mid = (max+min)/2;
while(true){
if(target>arr[mid]){
min = mid+1;
}else if(target<arr[mid]){
max = mid -1;
}else{
//找到了元素
return mid;
}
//没有找到的情况
if (max<min){
return -1;
}
//重新计算中间索引值
mid = (min+max)/2;
}
}
public static int searchEle(int[] arr, int target){
for(int i = 0 ; i<arr.length ; i++){
if(arr[i]==target){
return i;
}
}
return -1;
}
}
案例5:数组翻转
/*
需求: 定义 一个函数接收一个char类型的数组对象,然后翻转数组中的元素。
char[] arr = {'a','b','c','d','e'};
*/
class Demo13
{
public static void main(String[] args)
{
//System.out.println("Hello World!");
char[] arr = {'a','b','c','d','e'};
reverse(arr);
}
public static void reverse(char[] arr){
for(int startIndex = 0 ,endIndex = arr.length-1 ; startIndex<endIndex ; startIndex++,endIndex--){
char temp = arr[startIndex];
arr[startIndex] = arr[endIndex];
arr[endIndex] = temp;
}
//遍历数组,查看效果
System.out.print("目前的元素:");
for (int i = 0 ; i<arr.length ;i++){
System.out.print(arr[i]+",");
}
}
}
6、二维数组
二维数组: 二维数组就是数组中的数组。
一根 变量
一盒 20根 一维数组
一条 10包 20根 二维数组
二维数组 的定义格式:
数据类型[][] 变量名 = new 数据类型[长度1][长度2];
长度1:一条烟有多少盒。
长度2: 一盒烟有多少根。
二维数组 的初始化方式:
动态初始化:
数据类型[][] 变量名 = new 数据类型[长度1][长度2];
静态初始化:
数据类型[][] 变量名 = {{元素1,元素2...},{元素1,元素2...},{元素1,元素2...} ..}
举个栗子:
class Demo15{
public static void main(String[] args)
{
//定义了一个二维数组
int[][] arr = new int[3][4];
arr[1][1] = 100;
/*
System.out.println("二维数组的长度:"+ arr.length); // 3
System.out.println("二维数组的长度:"+ arr[1].length); //
*/
System.out.println("数组的元素:"+ arr[1][1]);
}
}
7、二维数组静态初始化
/*
静态初始化:
数据类型[][] 变量名 = {{元素1,元素2...},{元素1,元素2...},{元素1,元素2...} ..}
*/
class Demo16
{
public static void main(String[] args)
{
int[][] arr = {{10,11,9},{67,12},{33,35,39,40}};
//遍历二维数组
for(int i = 0; i <arr.length ; i++){
for(int j = 0 ; j<arr[i].length ; j++){
System.out.print(arr[i][j]+",");
}
//换行
System.out.println();
}
}
// 定义一个二维数组,然后计算二维数组中偶数元素的总和。
}
8、二维数组动态初始化:
int [][] a=new int [3][4];
for(int i=0;i<a.length;i++){
for(int j=0;j<a[i].length;j++){
a[i][j]=++value;
}
}
9、二维数组常见的操作:
(1)遍历二维数组
(2)对二维数组求和
package cn.itcast.day;
public class Demo1{
// 定义一个遍历二维数组的功能函数
public static void printArr2( int [][] a ){
// 1. 拆开二维数组
for ( int i = 0 ; i < a.length ; i++ )
{
// 2. 拆开一维数组获取数据
for ( int j = 0 ; j < a[i].length ; j++ )
{
System.out.print( a[i][j]+" ," );
}
}
}
// 定义一个函数计算二维数组中的元素的累加和
public static long getSum( int [][] a ){
// 0. 定义一个结果变量
long sum = 0L;
// 1. 拆开二维数组
for ( int i = 0 ; i < a.length ; i++ )
{
// 2. 拆开一维数组获取数据
for ( int j = 0 ; j < a[i].length ; j++ )
{
sum+=a[i][j];
}
}
return sum;
}
// 统计二维数组中元素的个数
public static int getDataCount( int [][] a ){
// 0. 记录元素个数
int count = 0;
// 1. 拆开二维数组
for ( int i = 0 ; i < a.length ; i++ )
{
// 2. 拆开一维数组获取数据
for ( int j = 0 ; j < a[i].length ; j++ )
{
count++;
}
}
return count;
}
public static void main(String[] args)
{
int [][] a = new int[][]{ {23,4,5},{2},{4,5,78,56,90} };
printArr2( a );
System.out.println();
System.out.println("累加和是: "+getSum( a ) );
System.out.println("统计元素个数: "+getDataCount( a ) );
System.out.println("Hello World!");
}
}
运行结果
23 ,4 ,5 ,2 ,4 ,5 ,78 ,56 ,90 ,
累加和是: 267
统计元素个数: 9
Hello World!
Process finished with exit code 0
参考自刘意java