数组:Array
数组的定义
数组的内存结构
数组定义常见问题
数组常见操作
Java参数传递问题--值传递
二维数组
1.数组概念
同一种类型数据的集合,可以是基本数据类型,也可以是引用数据类型。
数组的特点:
数组存储的都是相同数据类型的元素(相同数据类型)
数组的长度也就是数组中元素的个数(固定长度)
元素从0开始编号,编号也称“索引”:index(下标,角标)(从零开始)
数组中元素的访问方式是通过数组名+索引的方式:arr[1](索引访问)
数组的定义格式
2.数组的初始化
初始化方式1:
动态初始化:数组的创建和元素的赋值分开进行
格式:
元素类型[] 数组名 = new 元素类型[数组长度];
int[] arr = new int[3];
初始化方式2:
静态初始化:数组创建时就给数组元素赋值
格式:
元素类型[] 数组名 = new 元素类型[]{元素1,元素2,…};
int[] arr = new int[]{2,0,3,1};
静态初始化的简化写法
int[] arr = {2,0,3,1};
直接打印数组类型的变量,会发现结果是一段看不懂的字符串,这就是引用数据类型变量的特点,它实际上代表的是一段内存空间的十六进制表示形式.真正的数据在JVM的堆内存空间中。
note:动态初始的构成元素都是默认是初始化成默认值的。
3.内存结构
Java程序在运行时,为了提高运行效率,对内存进行了不同区域的划分,每一种区域都有特定的处理数据的方式和内存管理方式
主要有以下几种:
栈内存:用于存储局部变量,当数据使用完,所占空间会自动释放
堆内存:存放数组和对象,通过new建立的实例都存放在堆内存中
每一个实例都有内存地址值
实例中的变量都有默认初始化值
当实例不再被使用,会在不确定的时间被垃圾回收器回收
方法区:存放类文件和方法(面向对象部分再讲解)
本地方法栈:供本地方法使用,与操作系统相关
程序计数器--Program Counter:对字节码文件计数
数组的内存结构:不属于四类八种,所以占用两种内存
4.数组操作常见问题
5.数组的遍历
数组遍历:依次访问每个元素,访问的次数就是元素的个数,访问次数的确定:length属性(数组名.length)。
获取一个数组的最值(最大值,最小值)
改写:用键盘录入数组的长度和元素值
改写:数组元素随机生成,并获取最值
普通查找:获取指定元素第一次出现的索引
数组的复制:重点考察是否需要返回值
合并两个数组
data1= [1,2,3] data2 = [4,5,6]
练习:随机生成两个数组,并合并
抽取奇数索引的元素(偶数的自己练习)
数组的逆序(注意返回值类型)
练习
public classArrayDemo4{public static voidmain(String[] args){int[] arr = {8,5,6,9,-10,4};
System.out.println("最大值是: " +getMax(arr));
System.out.println("最小值是: " +getMin(arr));
}//自定义方法,获取一个数组的最大值
public static int getMax(int[] arr){int max = arr[0];//遍历余下的数,比较,大的就放在max中
for(int i = 1;imax){
max=arr[i];
}
}// returnmax;
}// public static int getMin(int[] arr){int min = arr[0];for(int i = 1;i
min=arr[i];
}
}returnmin;
}
}
获取一个int数组的最值
public classArrayDemo5{public static voidmain(String[] args){int[] arr = new int[5];//循环中产生随机值,并且赋值给元素
for(int i = 0;i
arr[i]=r;
}//打印数组元素
printArray(arr);//获取最值
System.out.println("最大值是: " +getMax(arr));
System.out.println("最小值是: " +getMin(arr));
}// public static int getMax(int[] arr){int max = arr[0];for(int i = 1;imax){
max=arr[i];
}
}returnmax;
}public static int getMin(int[] arr){int min = arr[0];for(int i = 1;i
min=arr[i];
}
}returnmin;
}// public static void printArray(int[] arr){for(int i = 0;i
System.out.print(arr[i]+ " ");
}
System.out.println();
}
}
在16-78之间产生5个随机数组成数组,并求出其中的最值
public classArrayDemo6{public static voidmain(String[] args){
Scanner s= newScanner(System.in);
System.out.print("输入元素的个数:");int n =s.nextInt();// int[] arr = new int[n];//赋值
for(int i = 0;i
System.out.println("输入第" + (i+1) + "个数:");
arr[i]=s.nextInt();
}//printArray(arr);
}// public static void printArray(int[] arr){for(int i = 0;i
System.out.print(arr[i]+ " ");
}
System.out.println();
}
}
改写:用键盘录入数组的长度和元素值
public classArrayDemo7{public static voidmain(String[] args){int[] arr = {1,2,3,4,5,10,8,2};
Scanner s= newScanner(System.in);
System.out.println("输入要找的元素:");int value =s.nextInt();int index =getIndex(arr,value);//根据返回值判断是否找到指定元素
if(index == -1){
System.out.println("没有找到对应的元素");
}else{
System.out.println("第一次出现的索引是: " +index);
}
}//int//int[] arr,int value
public static int getIndex(int[] arr,intvalue){/*for(int i = 0;i
if(arr[i] == value){
return i;
}
}
//程序执行到这,意味着没有发现和参数相等的元素,那就返回一个不存在的索引值
return -1;*/
//定义变量,保存返回值
int index = -1;for(int i = 0;i
index=i;break;//不加break,如果多次出现这个值,那么这里得到的是最后一次出现的索引
}
}returnindex;
}
}
普通查找:获取指定元素第一次出现的索引
public classArrayDemo8{public static voidmain(String[] args){int[] arr = {3,5,2,0};int[] res =copyArray(arr);
printArray(res);
System.out.println(arr== res);//true false
}// public static void printArray(int[] arr){for(int i = 0;i
System.out.print(arr[i]+ " ");
}
System.out.println();
}//自定义方法:实现数组的复制
public static int[] copyArray(int[] src){//创建一个新的数组:和源数组一样长
int[] dest = new int[src.length];//循环赋值
for(int i = 0;i
dest[i]=src[i];
}returndest;
}
}
数组的复制:重点考察是否需要返回值
/*合并两个数组
data1 = [1,2,3] data2 = [4,5,6]
分析:先创建一个大的数组:特点长度等于两个小数组长度之和.
然后依次赋值,重点是目标数组的索引的控制.
练习:随机生成两个数组,并合并
随机生成两个长度在1-10以内的数组,元组值范围:1-100
然后合并两个数组.*/
public classArrayDemo9{public static voidmain(String[] args){int[] data1 = {1,2,3};int[] data2 = {4,5,6,7,8,9};int[] dest =merge(data1,data2);
printArray(dest);
}//自定义方法,实现数组的合并
public static int[] merge(int[] arr1,int[] arr2){//创建一个大数组
int[] dest = new int[arr1.length +arr2.length];int index = 0;for(int i = 0;i
dest[index++] =arr1[i];//index++;
}for(int i = 0;i
dest[index++] =arr2[i];//index++;
}/*//循环赋值
for(int i = 0;i
dest[i] = arr1[i];
}
for(int i = 0;i
dest[arr1.length + i] = arr2[i];
}*/
returndest;
}// public static void printArray(int[] arr){for(int i = 0;i
System.out.print(arr[i]+ " ");
}
System.out.println();
}
}
合并两个数组
/*随机生成两个长度在1-10以内的数组,元素值范围:1-100
然后合并两个数组.*/
public classArrayDemo10{public static voidmain(String[] args){int l1 = (int)(Math.random() * 10) + 1;int[] arr1 = new int[l1];int l2 = (int)(Math.random() * 10) + 1;int[] arr2 = new int[l2];//循环赋值
for(int i = 0;i
arr1[i]= (int)(Math.random() * 100) + 1;
}//循环赋值
for(int i = 0;i
arr2[i]= (int)(Math.random() * 100) + 1;
}//打印
System.out.println("第一个数组是: ");
printArray(arr1);
System.out.println("-------------");
System.out.println("第二个数组是: ");
printArray(arr2);
System.out.println("-------------");
System.out.println("合并之后的数组是: ");
printArray(merge(arr1,arr2));
}//打印数组
public static void printArray(int[] arr){
System.out.print("[");for(int i = 0;i
System.out.print(arr[i]+ "]");
}else{
System.out.print(arr[i]+ ", ");
}
}
System.out.println();
}//合并数组
public static int[] merge(int[] src1,int[] src2){int[] dest = new int[src1.length +src2.length];int index = 0;for(int i = 0;i
dest[index++] =src1[i];
}for(int i = 0;i
dest[index++] =src2[i];
}returndest;
}
}
合并两个数组
public classArrayDemo11{public static voidmain(String[] args){int[] arr = {1,2,3,4,5,6,7,8,9,10};int[] odd =getOdd(arr);
printArray(odd);int[] even =getEven(arr);
printArray(even);
}//自定义方法,抽取偶数索引的元素
public static int[] getEven(int[] arr){//计算偶数元素的个数
int n = (arr.length + 1) / 2;//创建新数组
int[] dest = new int[n];int index = 0;//循环赋值
for(int i = 0;i
dest[index++] =arr[i];
}returndest;
}//自定义方法,抽取奇数索引的元素
public static int[] getOdd(int[] arr){//计算奇数索引的个数
int n = arr.length / 2;//创建目标数组
int[] dest = new int[n];int index = 0;//赋值
for(int i = 0;i
dest[index++] =arr[i];
}
}returndest;
}//打印数组
public static void printArray(int[] arr){
System.out.print("[");for(int i = 0;i
System.out.print(arr[i]+ "]");
}else{
System.out.print(arr[i]+ ", ");
}
}
System.out.println();
}
}
抽取奇数索引的元素
public classArrayDemo12{public static voidmain(String[] args){int[] arr = {1,2};
reverse(arr);
printArray(arr);
}//打印数组
public static void printArray(int[] arr){
System.out.print("[");for(int i = 0;i
System.out.print(arr[i]+ "]");
}else{
System.out.print(arr[i]+ ", ");
}
}
System.out.println();
}// public static void reverse(int[] arr){int n = arr.length / 2;for(int i = 0;i
arr[i]= arr[arr.length - 1 -i];
arr[arr.length-1 - i] =temp;
}
}
}
数组的逆序(注意返回值类型)void
6.Java中参数传递(实参->形参)的问题
public classTest5 {public static voidmain(String[] args) {int[] a = { 1, 2, 3, 4, 5};int[] b = new int[a.length];
System.out.println("交换前:");
print(a);
print(b);
b= swap(a);//交换
System.out.println("交换后:");
print(a);
print(b);
}public static void print(int[] arr){
System.out.print("[");for(int i = 0;i
System.out.print(arr[i]+ "]");
}else{
System.out.print(arr[i]+ ", ");
}
}
System.out.println();
}private static int[] swap(int[] c) {int[] tmp = new int[c.length];for (int j = 0; j < c.length; j++) {
tmp[j]= c[c.length - j - 1] + 10;
}returntmp;
}
}
值传递1
交换前:
[1, 2, 3, 4, 5]
[0, 0, 0, 0, 0]
交换后:
[1, 2, 3, 4, 5]
[15, 14, 13, 12, 11]
swap()方法时,数组a将其地址传递c,所以a和c是指向同一个数组。
但在swap方法中,新生成了一个数组tmp,改变的是tmp数组,返回时把tmp数组的首地址送数组b.所以b指向改tmp.
public classTest6 {public static voidmain(String[] args) {int[] a = { 1, 2, 3, 4, 5};int[] b = new int[a.length];
System.out.println("交换前:");
print(a);
print(b);
b=swap(a);
System.out.println("交换后:");
print(a);
print(b);
}public static void print(int[] arr){
System.out.print("[");for(int i = 0;i
System.out.print(arr[i]+ "]");
}else{
System.out.print(arr[i]+ ", ");
}
}
System.out.println();
}private static int[] swap(int[] c) {for (int j = 0; j < c.length; j++) {
c[j]= c[c.length - j - 1] + 10;
}returnc;
}
}
值传递2
交换前:
[1, 2, 3, 4, 5]
[0, 0, 0, 0, 0]
交换后:
[15, 14, 13, 24, 25]
[15, 14, 13, 24, 25]
说明: 在该程序中,在调用swap()方法时,数组a将其地址传递给数组c,所以a和c是指向同一个数组。
返回时,数组b不再指向原来的数组,而指向c所在的数组。
注: JAVA中参数传递时是值传递,引用型与基本数据类型是不同的.
7 二维数组
7.1二维数组的概念
7.2 二维数组的定义
注意事项:
1.使用格式1,2时必须指定第一维长度
2.动态,静态初始化不能同时使用
7.3二维数组的遍历
8 数组的排序(排序算法)
8.1冒泡排序:bubble
冒泡排序(BubbleSort)的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面。即首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。重复以上过程,仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),将小数放前,大数放后,一直比较到最大数前的一对相邻数,将小数放前,大数放后,第二趟结束,在倒数第二个数中得到一个新的最大数。如此下去,直至最终完成排序。
/** 冒泡排序:
* 相邻的元素两两比较.大的往后放.*/
public classBubbleSortDemo {public static voidmain(String[] args) {int[] arr = {9,5,2,0,4,5,5,7};
bubbleSort(arr);
printArray(arr);
}public static void printArray(int[] arr){for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+ " ");
}
System.out.println();
}// public static void bubbleSort(int[] arr){//外层循环控制的是比较的趟数:固定是元素个数-1
for(int i = 0;i
for(int j = 0;j arr[j + 1]){int temp =arr[j];
arr[j]= arr[j + 1];
arr[j+ 1] =temp;
}
}
}
}
}
冒泡排序
8.2 比较排序:compare(选择排序:select)
/** 选择排序*/
public classSelectSortDemo {public static voidmain(String[] args) {//TODO Auto-generated method stub
int[] arr = {9,5,2,7,0,6,4,7};
selectSort(arr);
print(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 void selectSort(int[] arr){//外层控制的是比较的趟数
for (int i = 0; i < arr.length -1; i++) {//内层循环控制的是两两比较元素的索引值
for (int j = i + 1; j < arr.length; j++) {// if(arr[i] >arr[j]){int temp =arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
}
}
选择排序
public classSelectSortDemo2 {public static voidmain(String[] args) {//产生1000个元素的数据进行比较
int[] arr1 =getArray();int[] arr2 =arrayCopy(arr1);
print(arr1);
print(arr2);long start =System.currentTimeMillis();
selectSort(arr1);
System.out.println(System.currentTimeMillis()-start);
start=System.currentTimeMillis();
selectSort2(arr2);
System.out.println(System.currentTimeMillis()-start);
System.out.println("排序后");
print(arr1);
print(arr2);
}public static int[] arrayCopy(int[] arr){int[] dest = new int[arr.length];
System.arraycopy(arr,0, dest, 0, arr.length);returndest;
}//随机生成1000个元素的int数组
public static int[] getArray(){int[] arr = new int[1000];for(int i = 0;i
arr[i]= (int)(Math.random() * 1000);
}returnarr;
}public static void print(int[] arr){for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+ " ");
}
System.out.println();
}public static void selectSort(int[] arr){int count = 0;//外层控制的是比较的趟数
for (int i = 0; i < arr.length -1; i++) {//内层循环控制的是两两比较元素的索引值
for (int j = i + 1; j < arr.length; j++) {// if(arr[i] >arr[j]){int temp =arr[i];
arr[i]=arr[j];
arr[j]=temp;
count++;
}
}
}
System.out.println("优化前的方法中,交换的次数是: " +count);
}public static void selectSort2(int[] arr){int count = 0;//外层控制的是比较的趟数
for (int i = 0; i < arr.length -1; i++) {//记录要确定的元素的索引号
int index =i;//内层循环控制的是两两比较元素的索引值
for (int j = i + 1; j < arr.length; j++) {// if(arr[index] >arr[j]){
index=j;
}
}//对index值进行判断
if(i !=index){int temp =arr[i];
arr[i]=arr[index];
arr[index]=temp;
count++;
}
}
System.out.println("优化后的方法中,交换的次数是: " +count);
}
}
选择排序比较
9 Arrays工具类
一下皆为静态方法。
binarySearch:复制指定的数组
copyOf:复制指定的数组
copyOfRange:将指定数组的指定范围复制到一个新数组
deepEquals:如果两个指定数组彼此是深层相等
deepToString:返回指定数组“深层内容”的字符串表示形式。
deepHashCode:基于指定数组的“深层内容”返回哈希码。
equals:如果两个指定的 某 型数组彼此相等,则返回 true。
fill: 将指定的 某型 值分配给指定 某 型数组的每个元素。
sort:根据元素的自然顺序对指定某类型数组按升序进行排序。
toString:返回指定数组内容的字符串表示形式。
单独介绍一下二分查找:
public classBinarySearchDemo {public static voidmain(String[] args) {int[] arr = {1,2,3,7,9,20};int index = getIndex(arr,1);if(index == -1){
System.out.println("not found");
}else{
System.out.println("the index is : " +index);
}
}//二分查找算法
public static int getIndex(int[] arr,intvalue){int min = 0;int max = arr.length - 1;int mid = (min + max)/2;while(true){// if(arr[mid] ==value){returnmid;
}else if(arr[mid] >value){
max= mid - 1;
}else{
min= mid + 1;
}//重新计算mid的值
mid = (min + max)/2;// if(min >max){return -1;
}
}
}
}
二分查找:前提:数组必须有序: