数组的基本概念
为什么要使用数组
假设要存入5个学生的考试成绩
public static void main(String[] args){
int score1=70;
int socre2=80;
int score3=85;
System.out.println(score1);
System.out.println(score2);
System.out.println(score3);
所有成绩的类型是相同的,Java中存在可以存储相同类型的多个数据类型。
什么是数组
数组:可以看作是相同类型元素的集合。在内存中是一段连续的空间。
在Java中,包含六个整形类型的元素的数组,相当于上图的六个车位,从中可以发现:
1.数组中存放的元素其类型相同
2.数组的空间是连在一起的
3.每个空间有自己的编号,其位置的编号为0,即数组下标。
数组的创建和初始化
public static void main(String[] args){
int[] array={1,2,3,4,5};
int[] array2=new int[]{1,2,3,4,5};
创建
T[] 数组名=newT[N];
T:表示数组中存放元素的类型
T[]:表示数组的类型
N:表示数组的长度
int[] array1=new int[10];//创建一个可以容纳10个int类元素的数组
初始化
数组分为动态初始化和静态初始化
1.在创建数组时,直接指定数组中的元素个数
in[] array =new int[10];
2.在创建数组时不直接指定数据元素个数,而直接将具体的数据内容进行指定
语法格式
T[]数组名称={data1,data2};
注意事项:
- 静态初始化虽然没有指定数组长度,编译器会根据{}中元素个数来确定数组长度。
- 静态初始化时,{}中数据类型必须与[]前数据类型一致
- 静态初始化可以简写,省去后面的new[]
- 如果没有对数组进行初始化,数组中元素有其默认值
- 如果数组中存储元素类型为基本类型,默认值为基类类型的对应默认值。
- 如果数组中储存类型为引用类型,默认值为null
数组的使用
元素访问
数组在内存中是一段连续的空间,空间编号是从零开始,依次递增,该编号为数组的下标,数组可以通过下标访问其任意位置的元素。
int[]array=new int[]{10,20,30,40};
System.out.println(array[0]);
System.out.println(array[1]);
System.out.println(array[2]);
System.out.println(array[3]);
注意
数组是一段连续的空间,因此支持随机访问,即通过下标访问快速访问数组中任意位置的元素
下标从0开始,介于【0,N)之间不包含N,N为元素个数,不能越界。
遍历数组
- 所谓遍历就是将数组的所有元素都访问一遍,访问是指对数组中的元素进行某些操作。
int[] array={1,2,3,4,5};
//array.length 可以求得数组长度
for (int i=0;i<array.length;i++)
{
Sytem.out.print(array[i]+" ");
}
System.out.println(array.length);
for(int x:array){
System.out.print(x+" ");
}
System.out.println();//增强for循环
遍历array把里面的元素每个都取出来,放到x里面
java :将数组里面的值,以字符串的形式组织一下然后进行打印
System.out.println(Arrays.toString(array));
头文件: import java.util.Arrays
数组的引用类型
初始JVM的内存分布
1.程序运行代码时需要加载到内存
2.程序运行产生的中间数据也存放内存
3.程序中常量也要保存
基本类型变量与引用类型变量
基本数据类型创建变量,称为基本变量,该变量空间直接存放的是其所对应的值。
而引用数据创建的变量,一般称为对象的引用,其空间中储存的是对象所在空间的地址。
public static void func(){
int a=20;
int b=10;
int arr[]=new int[]{1,2,3};
}
//上述代码中,a,b,arr都是函数内部的变量因此其空间都在main方法对应的栈中分配。
array是数组类型的引用变量,其内部保存的内容可以简单理解成是数组在堆空间中的首地址。
引用变量并不直接储存对象本身,可以简单理解为存储的是对象在堆中空间的起始地址。通过该地址,引用变量便可以去操作对象。
int[] array={1,2,3,4,5};
System.out.println(array[10]);
int[] array2=null;
System.out.println(array2[0]);
NULL在java中是空引用,表示一个无效的内存位置。因此不能对这个内存进行任何读写操作,一旦尝试读写,就会抛出NullPointerExecption
int[] array={1,2,3,4,5};
int[] array2=array;
String ret1=Array.toString(array);
String ret2=Array.toString(array);
array2这个引用指向了array这个引用所指向的对象。
数组的应用场景
保存数据
public static void main(String[] args){
int[] array={1,2,3};
for(int i=0;i<array.length;++i){
System.out.println(array[i]+"");
}
}
作为函数的参数
1.参数传基本数据类型
public static void main(String[] args){
int[] array={1,2,3,4,5};
printf(array);
}
public static void print(int[] array){
for(int i=0;i<array.length;i++)
{
System.out.println(aray[i]+" ");
}
}
当要打印`System.out.println(array[0]); 结果是8
public static void func1(int[] array){
//调用
array=new int[]{9,8,7,6};
}
当函数调用时,会调用上面的array不会调用新添加的。
当调用函数func1(array);
public static void func1(int[] array){
//调用
array=new int[]{9,8,7,6};
}
但程序执行完后,在栈中的array会自动销毁,
栈中只有一个array。
发现在func方法内部修改数组的内容,方法外部的数组内容也会发生改变。
因为数组是引用类型,按照引用类型来进行传递,是可以修改其中存放的内容的。
作为函数的返回值
puclic static void main(String[] args){
int[] ret=func2();
System.out.println("后:”+Arrays.toString(ret));
}
public static int[] func2(){
return new int[]{111,22};
}
数组练习
输出[1,2,3,4,5,6]
pubic static String myToString(int[] array){
if(array==null)
{
return "null";
}
String try="[";
for(int i=0;i<array.length;i++){
ret +=array[i];
if(i!=array[i];
ret +=",";
}
ret +="]";
}
查找数组里面指定元素(二分查找)
针对有序数组,可以更高效的二分查找
以升序数组为例,二分查找的思路先取中间位置的元素,然后使用待查找元素与数组中间元素进行比较:
- 如果相等,即找到了返回该元素在数组中的下标。
- 如果小于,以类似方式到数组左半侧查找。
- 如果大于,一类似方式到数组右半侧查找。
int[] array={1,2,3,4,5,6,7};
int index=binarySearch(array,key:5);
piblic static int binarySearch(int[] array,int key){
int left =0;
int right=array.length-1;
while(left<right){
int m=(left+right)/2;
if(array[m]>key){
right=m-1;
}
else if(array[m]<key){
left =m+1;}
else {
return m;
}
}
return -1;
}//必须是建立在你查找的数据是有序的情况下
System.out.println(index);}
piblic statuc int findVal(int[] array,int key){
for(int i=0;i<array.length;i++){
if (array[i]==key){
return i;
}
}
无序排序
int[] array={1,2,13,4,5,16,7};
Arrays.sort(array);
System.out.println("排序后的数组:"+Arrays.toString(array));
int index=Arrays.binarySearch(array,key:5);
System.out.println(index);
数组排序(冒泡排序)
给定一个数组,让数组升序(降序)排序。
算法思路
假设排升序:
1.将数组中相邻元素从前往后依次进行比较,如果前一个元素比后一个元素大,则交换,一趟下来后最大元素就在数组的末尾。
2.依次从上上述过程,直到数组中所有的元素都排列好。
public static void bubbleSort(int[] array){
for(i=0;i<array.length-1;i++)
//控制每趟比上一趟少1
{
boolean flg=false;// i代表趟数
for(int j=0;j<array.length-1;j++)
{
if(array[j]>array[j+1]){
int tmp=array[j];
array [j]=array [j+1];
array[j=1]=tmp;
flg=true;
}
}
if(flg==flase){
break;
}
数组拷贝
头文件 import java.util.Arrays;
public static void main(String[] args){
int[] array={1,2,3,4,5};
int[] ret=copy(array);
System.out.println(Arrays.toString(ret));
System.out.println("==========");
int[] ret=Array.copyOf(array,newlength:length*2);
System.out.println(Array.toString(ret));
}
public static int[] copy(int[] array){
int[] copyArray =new int[array.length];
for(int i=0;i<array.length;i++)
{
copyArray[i]=array[i];
}
return copyArray;
}
public static void func(){
//newArr和arr引用的是同一数组。
//因此newArr修改空间中内容之后,arr也可以看到修改的结果。
int[] arr={1,2,3,4,5,6};
int[] newArr[0]=arr;
newArr[0]=10;
System.out.println("newArr:"+Array.toString(newArr));
//因为arr修改其印用的数组内容时,对newArr没有任何影响、
}
public static void main(String[] args){
int[] array={1,2,3,4,5};
int[] ret=Arrays.copyOfRange(arra,from:1,to:3);
System.out.println(Array.toString(ret));
}
上述代码输出结果为[2,3];
数组的逆序
给定一个数组,将里面的元素逆序排序。
思路:
设定两个下标,分别指向第一个元素和最后一个元素,交换两个位置元素。然后让前一个下标自增,后一个下标自减,循环继续。
public static void main(String[] args){
int[] array={1,2};
reverseArray(array);
System.out.println(Array.toString(array));
}
public static void reverseArray(int[] array){
int i=0;
int j=array.length;
while(i<j){
int tmp=array[i];
array[i]=array[j];
array[j]=tmp;
i++;
j--;
}
二维数组
基本语法
数据类型[][]数组名称=new 数据类型[行数][列数]{初始化};
public class Text{
public static void main(String[] args){
int[][]array1={{1,2,3},{4,5,6}};
int[][]array2=new int[2][3];
int[][]array3=new int[][]{{1,2,3}{4,5}};
for(int i=0;i<array1.length;i++){
for(int j=0;j<array1[i].length;j++){
System/out.println(array[i][j]+" ");
}
System.out.println();
}
第二种
int [][]array1={111,2,3}{4,5,6}};
System.out.println(array1.length);
//每一行的长度
System.out.println(array1[1].length);
//每一列的长度
第三种
for(int[] tmp :array){
for(int x :tmp){
System.out.print(x+" ");
}
System.out.println();
}
java当中可以省略行,不能省略列。