数组的定义与使用(附练习题)

上一篇:循环和递归的优缺点

1、数组定义:存放相同类型数据的集合。内存是连续的。数组可以通过下标来访问其中的元素。
数组最大的缺陷:长度固定,创建数组之后不能修改数组的大小,可以使用length属性获取数组的大小。

2、创建一维数组

// 动态初始化
 int[] array = new int [ ] { 1,2,3,4,5 }; 
// 静态初始化
 int[] array = { 1,2,3,4,5 };
 int[ ] arr=new int[10];     //只是定义了一个数值,默认值为0。

注意
int [ ] arr={1,2,3};
其中数组名arr所存储的内容在栈上,是存放初始化数据的地址。
初始化的数据{1,2,3}是存储在堆上的。

创建二维数组:

		int[][] array = {{1,2,3},{4,5,6}};
        int[][] array2 = new int[][]{{1,2,3},{4,5,6}};
        int[][] array3 = new int[2][3];
        int[][] array4 = new int[2][];
        int[][] array5 = {{1,2},{4,5,6}};
        //c语言中二维数组必须指定列,行可以自动推导;而Java中二维数组行必须指定,列不可以自动推导。

Java中的二维数组实质上就是一维数组,当中的每个元素都是一维数组(二维数组就是特殊的一维数组)。
理解如图:
在这里插入图片描述

3、下标访问操作不能超出有效范围 [0, length - 1] , 如果超出有效范围, 会出现下标越界异常。
eg:ArrayIndexOutOfBoundsException: 数组越界异常。

另外,数组属于引用数据类型,所以在数组使用之前一定要开辟空间(实例化),如果使用了没有开辟空间的数组,则一定会出现 NullPointerException 异常信息:
NullPointerException即:空指针异常

4、java基本数据类型传递参数时是值传递;引用类型传递参数是引用传递。
数组引用传递
引用:就是存放地址的。引用传递的本质是:同一块堆内存空间可以被不同的栈内存所指向。

5、一维数组的遍历:
1)For()循环

public static void main(String[] args) {
    int[] arr={1,2,3};
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

2)foreach

int[] arr = {1, 2, 3};
 for (int x : arr) {
     System.out.println(x); 
 } 
 // 执行结果 1 2 3(不能按下标单独打印)
//x :数组当中的元素   array:需要打印的数组名

3)Arrays.toString();

//将数组以字符串的形式进行打印
System.out.println(Arrays.toString(array3));

模拟Arrays.toString();方法

public static String toString(int[] array) {
        String str = "[";
        for (int i = 0; i < array.length; i++) {
            str = str + array[i];
            if(i != array.length-1) {
                str += ", ";
            }
        }
        str += "]";
        return str;
    }

二维数组的遍历

for (int i = 0;i < array.length; i++) {
	for(int j = 0; j< array[i].length; j++) {
		System.out.print(array[i][j] + " ");
	}
	System.out.println();
}

//常用
System.out.println(Arrays.deepToString(array));

for (int[] tmp:array) {
            for (int x:tmp) {
                System.out.print(x + " ");
            }
            System.out.println();
        }

6、JVM内存区域划分
JVM:
在这里插入图片描述

  • 程序计数器:存放下一条指令(内存很小)
  • Java虚拟机栈:平时说的栈,主要用来存放局部变量表
  • 本地方法栈:主要用来调用native方法,存放native方法的局部变量。Native方法:是由C/C++代码实现的方法。一般体现在源码当中。
Public static native void arraycopy(Object src,
									int srcPos,Object dest,int destPos,int length);
  • 堆:主要用来存放对象的。使用 new 创建的对象都是在堆上保存 (例如前面的 new int[]{1, 2, 3} ) (堆的空间非常大,栈的空间非常小)
  • 方法区:用来存放静态变量,类信息。
  • 类信息:class对象。
  • 常量池:主要用来存放字符串常量。String str = “hello”;就存放在常量池。在JDK1.以前,常量池放在方法区。在JDK1.7开始,他被挪到了堆里面。

7、地址的哈希码是真实的地址哈希出来的
哈希表:地址是唯一的,哈希码也是唯一的。

8、每个线程都会有三块独立的内存区域:程序计数器,JAVA虚拟机栈,本地方法栈
在这里插入图片描述

9、 8种简单类型对应的0值:
Char \u0000 boolean:false
引用类型:null
运算符: . 一般来说, . 属性 , . 行为(方法)
按值传递:形参就是实参的一个拷贝。
Arrays:是java当中操作数组的工具类,将数组以字符串的形式打印

10、Object:是所有类型的父类
Java.util.Arrays:操作数组的常用类
Java.util.:工具类

Arraycopy(Object src,int srcPos,Object dest,int destPos,int length)

其中:src:代表源数组
srcPos:从源数组的pos位置开始拷贝
dest:目的地数组
destPos:目的地数组的位置
length:拷贝的长度
copyOf(int [] 源数组,int 拷贝的长度)
注意:
Arrays.copyOf()返回值是void
System.arraycopy();返回值是int
Arrays.copyOf()底层调用的是System.arraycopy();
System.arraycopy();更快

11、数组的拷贝:
1)、for循环去拷贝

for (int i = 0; i < array.length; i++) {
            array2[i] = array[i];
        }

2)、System.arraycopy

  System.arraycopy(array,
            0,array2,0,array.length);

3)、Arrays.copyOf

//int[] array2 = Arrays.copyOf(array,array.length);

4)、数组名.clone();

  • 返回一个副本
    * 数组名->你要拷贝的数组
    * clone是Object的方法
int[] array2 = array.clone();
System.out.println(Arrays.toString(array2));

拷贝分为:
深拷贝:不会改变数组值
浅拷贝:……

四种拷贝方式,对于数组当中如果是简单类型那么就是深拷贝;
对于与数组当中如果是引用类型那么就是浅拷贝。

以上四种类型可以对引用类型的数组进行深拷贝,但是代码的写法要进行改变

12、学习Arrays类当中的方法:

 * Arrays.toString();
 * Arrays.copyOf();
 * Arrays.copyOfRange();//拷贝部分数组[)
 * Arrays.binarySearch();
 * Arrays.equals();判断数组是否相同
 * Arrays.fill(array,9); 数组的填充
 * Arrays.fill(array,2,7,88);[2,7)下标填充为88
 * Arrays.sort(array);将数组进行排序

Array.deepToString(array);打印全部数组。

13、程序练习
1)将数组当中奇数放到偶数前面

public static void eveAfterOdd(int[] array) {
        int i = 0;
        int j = array.length-1;
        while (i < j) {
            while (i < j && array[i] % 2 != 0) {
                i++;
            }//i所保存的下标就是偶数的下标

            while (i < j && array[j] % 2 == 0) {
                j--;
            }//j所保存的下标就是奇数的下标

            if(i < j) {
                int tmp = array[i];
                array[i] = array[j];
                array[j] = tmp;
            }
        }
}

2)实现二分查找代码
i)

public static int binarySearch1(int[] array,int key) {
        int left = 0;
        int right = array.length-1;

        while (left<=right) {
            //int mid = (left+right)/2;
            int mid = (left+right)>>>1;
            if(array[mid] == key) {
                return mid;
            }else if(array[mid] < key) {
                left = mid+1;
            }else {
                right = mid-1;
            }
        }
        return -1;
    }

ii)将上述程序level 一个层次

public static int binarySearch(
            int[] array,int key,int left,int right) {
        if(left > right) {
            return -1;
        }
        int mid = (left+right)>>1;
        if(array[mid] == key) {
            return mid;
        }else if(array[mid] > key) {
           return binarySearch(array,key,left,mid-1);
        }else {
            return binarySearch(array,key,mid+1,right);
        }
    }

3)数组的逆置

public static void reverse(int[] array) {
        int i = 0;
        int j = array.length-1;
        while (i < j) {
            int tmp = array[i];
            array[i] = array[j];
            array[j] = tmp;
            i++;
            j--;
        }
    }

4)冒泡排序

class BubbleSort{
	void printIntArray(int[] arr)
	{
		for(int x : arr){
			System.out.print(x + " ");
		}
		System.out.println();
	}
	
	void sort(int[] arr)
	{
		int temp = 0;
		for(int i = 1;i < arr.length;i++){
			for(int j = 0;j < arr.length - i;j++){
				if(arr[j] > arr[j + 1]){
					temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
				}
			}
		}
	}
}

将上述程序稍加改动,当程序在进行中时已再无任何交换,即可提前结束,减少运算

public static void bubbleSort(int[] array) {

        boolean flg = false;
        //趟数
        for (int i = 0; i < array.length-1; i++) {
            flg = false;//因为每一趟都有能有序
            //次数
            for (int j = 0; j < array.length-1-i; j++) {
                if(array[j] > array[j+1]) {
                    int tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = tmp;
                    flg = true;
                }
            }
            if(!flg) {
                return;
            }
        }
    }

下一篇:JAVA类和对象
在这里插入图片描述

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值