Java基础——数组(自学分享)

数组

介绍

什么是数组

是一种引用数据类型。
是一种常见的数据结构,存储相同数据类型的数据。
使用一个统一的数组名和不同的下标来唯一确定数组中的元素。
是在内存中存储相同数据类型的连续空间。
简单的线性序列,访问速度快。
元素在数组中的排序叫做下标,从0开始。
数组的长度一旦声明,就不能改变了。
数值数组元素的默认值为 0,而引用元素的默认值为 null。

特性

  • 一致性:可以保存任何相同数据类型的元素。
  • 有序性:元素有序,通过下标访问。
  • 不可变性:一旦初始化,长度(元素的个数)不可变。

分类

一维数组

实质上是一组相同类型数据的线性集合,是最简单的一种数组。

声明数组

声明数组的时候不需要定义长度。
但是声明时,类型后边必须跟中括号”[]“。
声明的是存放数组的变量,并没有分配内存空间,还不能使用。

数组类型[] 数组名;(推荐使用,可读性强)

比如:
int[] intArray;//声明一个int类型的数组
String[] strArray;//声明一个string类型的数组

可以使用new来告诉程序为数组分配空间。

数组类型[] 数组名 = new 数组类型[数组长度];

比如:
int[] arr= new int[5];//声明一个int类型的数组,并定义它的长度为5

arr数组在内存中的格式是这样的:
在这里插入图片描述
图中的arr是数组的名称,中括号”[]“中的值代表数组的小标,数组中是通过下标来区分元素的,下标从0开始数组大小一旦声明就不能更改

当声明一个数组变量时,其实是创建了一个类型为“数据类型[]”(如 int[]、double[]、String[])的数组对象,它具有下表所示的方法和属性:

方法名返回值
clone()Object
equals(Object obj)boolean
getClass()Class<?>
hashCode()int
notify()void
notify All()void
toString()String
wait()void
wait(long timeout)void
wait(long timeout,int nanos)void
length(这个是属性)int
初始化数组

数组必须要初始化才能使用,就是为数组元素分配内存空间,并为每个数组元素赋初始值。
为数组元素分配内存空间,其实就是将数组中的元素存储到每个内存空间中,即使内存空间存储的内容为空,它的值就用null。

有两种方式获取初始值:

  • 1、系统自动分配。
  • 2、自定义来指定。
  • 1、使用new指定数组大小后初始化:

使用new关键字创建数组,并指定数组的大小。
元素赋值时才能确定值。

//创建数组后,元素的值并不确定,要为数组中的每一个元素赋值,下标从0开始。
数据类型[] 数组名 = new 数据类型[数组长度];
int[] intArray = new int[5];
intArray[0] = 1;
intArray[1] = 2;
intArray[2] = 3;
intArray[3] = 4;
intArray[4] = 5;

如果只指定了数组的长度,系统会自动为数组分配初始值。

  • 整数类型(byte、short、int、long),元素值为0。
  • 浮点类型(float、double),元素值为0.0。
  • 字符类型(char),元素值为’\u0000’。
  • 布尔类型(Boolean),元素值为false。
  • 引用类型(类、接口、数组),元素值为null。
  • 2、使用new指定数组元素的值

初始化的时候就指定元素的值。
这时中括号中不指定数组的长度。

数据类型[] 数组名 = new 数据类型[]{1,2,3,....};
int[] intArray = new int[]{1,2,3,4,5};

注意:

  • 不能在进行数组初始化时,既指定长度又指定元素的值,int[] intArray = new int[5]{1,2,3,4,5};这样编译报错。Cannot define dimension expressions when an array initializer is provided
  • 3、直接指定数组元素的值

不使用new关键字。

数据类型[] 数组名 = {1,2,3,.....};
int[] intArray = {1,2,3,4,5};

注意:

  • 数组的声明和初始化要同步,
    int[] intArray ; intArray = {1,2,3,4,5};这样会编译错误,Array constants can only be used in initializers
获取元素

通过下标获取元素。

  • 获取单个元素
  • 适合数组元素数量不多的时候。
int[] arr = {1,2,3,4,5};
System.out.println("获取数组arr中的第一个元素:"+arr[0]);//获取数组arr中的第一个元素:1
System.out.println("获取数组arr中的第三个元素:"arr[2]);//获取数组arr中的第三个元素:3
System.out.println("获取数组arr中的第六个元素:"+arr[5]);//运行错误,数组下标越界:java.lang.ArrayIndexOutOfBoundsException

注意:

  • 数组的下标超过了(数组的长度-1)时,会出现运行时错误:数组下标越界:java.lang.ArrayIndexOutOfBoundsException
  • 遍历数组(获取数组中的所有元素)

可以获取数组的全部元素。
适合数组中元素比较多的时候。

int[] arr = {1,2,3,4,5};
for (int i = 0; i < arr.length; i++) {
	System.out.println("第"+i+"个元素是:"+arr[i]);
}

运行结果为:
第1个元素是:12个元素是:23个元素是:34个元素是:45个元素是:5
int[] arr = {1,2,3,4,5};
for (int i : arr) {
	System.out.println("元素的值依次是:"+i);
}

运行结果为:
元素的值依次是:1
元素的值依次是:2
元素的值依次是:3
元素的值依次是:4
元素的值依次是:5

二维数组

二维数组被称作数组的数组,就是数组里边定义了数组。
特殊的一维数组,数组中的元素又是一个一维数组。

声明二维数组
数据类型[][] 数组名;//第一个中括号表示行,第二个中括号表示列。
int[][] intArray;
初始化二维数组
  • 1、使用new指定大小后初始化
数据类型[][] 数组名 = new 数据类型[外层数组长度][内层数组长度];
int[][] arr1 = new int[2][2];//定义int类型2行2列的二位数组
arr1[0][0] = 1;
arr1[0][1] = 2;
arr1[1][0] = 3;
arr1[1][1] = 4;

二维数组内存结构图:
在这里插入图片描述

  • 2、使用new指定数组元素的值

这时候不指定数组的长度。

数据类型[][] 数组名 = new 数据类型[][]{{1,2,...},{1,2,...},...};
int[][] arr2 = new int[][]{{1,2},{3,4}};//2行2列的二维数组,并指定了元素的值

注意:

  • 使用new初始化二位数组的时候,不能既指定长度又指定元素的值,编译错误:Cannot define dimension expressions when an array initializer is provided
  • 3、直接指定数组元素的值
数据类新[][] 数组名 = {{1,2,...},{1,2,...},...}
int[][] arr3 = {{1,2},{3,4}};//2行2列的二维数组
获取元素

通过下标获取。
行和列的下标都是从0开始。

  • 获取单个元素
int[][] arr3 = {{1,2,3,},{4,5,6,7}};
System.out.println("第1行1列的值:"+arr3[0][0]);
System.out.println("第2行3列的值:"+arr3[1][2]);
System.out.println("第3行1列的值:"+arr3[2][0]);//运行报错:数组下标越界了

运行结果为:
第11列的值:123列的值:6
java.lang.ArrayIndexOutOfBoundsException
  • 遍历数组

arr.length获取的是数组的行数,arr[i].length获取的是该行的列数,也就是元素数。

//for循环遍历
int[][] arr3 = {{1,2,3},{4,5,6,7}};
for (int i = 0; i < arr3.length; i++) {
	for (int j = 0; j < arr3[i].length; j++) {
		System.out.println("第 "+(i+1)+" 行第 "+(j+1)+" 列的值是:"+arr3[i][j]);
	}
	System.out.println("上边是第 "+(i+1)+" 行的元素值");
}

运行结果为:
第 1 行第 1 列的值是:11 行第 2 列的值是:21 行第 3 列的值是:3
上边是第 1 行的元素值
第 2 行第 1 列的值是:42 行第 2 列的值是:52 行第 3 列的值是:62 行第 4 列的值是:7
上边是第 2 行的元素值
//for each循环遍历
int[][] arr3 = {{1,2,3},{4,5,6,7}};
for (int[] is : arr3) {
	for (int i : is) {
		System.out.println(i);
	}
}

运行结果为:
1
2
3
4
5
6
7
快速打印输出二维数组
int[][] arr3 = {{1,2,3},{4,5,6,7}};
System.out.println(Arrays.deepToString(arr3));

运行结果为:
[[1, 2, 3], [4, 5, 6, 7]]

多维数组

多维数组其实就是相当于几维数组,就有几个中括号。
其实二维数组也是多维数组。

声明多维数组
数据类型[][][].. 数组名;
int[][][] arr;
初始化多维数组
int[][][] arr1 = new int[2][3][4];//三层数组,从外往里数:第一层有两个元素,第二层有三个元素,第三层有四个元素。
int[][][] arr2 = new int[][][]{
								{//第一层的第一个元素
									{1,2,3,4},
									{5,6,7,8,},
									{9,10,11,12}
								},
								{//第一层的第二个元素
									{13,14,15,16},
									{17,18,19,20},
									{21,22,23,24}
								}
							  };

for (int i = 0; i < arr2.length; i++) {
	for (int j = 0; j < arr2[i].length; j++) {
		for (int j2 = 0; j2 < arr2[i][j].length; j2++) {
			System.out.print(arr2[i][j][j2]+",");
		}
		System.out.println("最内层==="+arr2[i][j].length+"个");
	}
	System.out.println("第二层===="+arr2[i].length+"个");
}
System.out.println("最外层====="+arr2.length+"个");

运行结果为:
1,2,3,4,最内层===45,6,7,8,最内层===49,10,11,12,最内层===4个
第二层====313,14,15,16,最内层===417,18,19,20,最内层===421,22,23,24,最内层===4个
第二层====3个
最外层=====2

遍历

  • for循环
  • 增强for循环(for-each)
  • Arrays.toString(数组名)方法
public static void main(String[] args){

	int[] arr = {1,2,3,4,5};
	
	//for循环
	for (int i = 0; i < arr.length; i++) {
		System.out.print(i+" ");
	}
	
	System.out.println();
	
	//增强for循环(for-each)
	for (int i : arr) {
		System.out.print(i+" ");
	}
	
	System.out.println();
	
	//Arrays.toString()
	String str = Arrays.toString(arr);
	System.out.println(str);
}

运行结果为:
0 1 2 3 4 
1 2 3 4 5 
[1, 2, 3, 4, 5]

冒泡排序

依次比较相邻的两个数值的大小,根据具体的排序要求进行移位存放;
从小到大排序,将大数后移;
从大到小排序,将大数迁移;
比如要从小到大排序,那么就是第一个数和第二个数比,大的后移;再拿大的数和第三个数比,大数后移;依次比较,直到最大值到达最右侧位置,这是的第一轮比较结束。第二轮比较和第一轮一样,但是不会再去和最右侧的最大值进行比较,当第二轮比较结束后,这一轮的最大值显然要小于第一轮的最大值,所以将其放在此轮比较的最右侧(这是它的右侧有一个比它大的值)。这样依次比较,直至结束。

//冒泡排序
int[] arr = {1,5,2,6,8,3,9,4,7};
int temp = 0;
System.out.println("从小到大的排序:");
for (int i = 0; i < arr.length-1; i++) {
	for (int j = 0; j < arr.length-i-1; j++) {
		if(arr[j]>arr[j+1]){
			temp = arr[j];
			arr[j]=arr[j+1];
			arr[j+1]=temp;
		}
	}	
}
for (int i = 0; i < arr.length; i++) {
	System.out.print(arr[i]+" ");
}

运行结果为:
从小到大的排序:
1 2 3 4 5 6 7 8 9 

Arrays工具类

包含了很多数组常用的方法。这些方法都是static修饰的。

  • Boolean equals(type[] a,type[] b)

比较两个数组是否相等。

public static void main(String[] args){
	int[] arr = {1,5,2,6,3,7,4,8};
	int[] arr1 ={1,2,3,4,5,6,7,8};
	int[] arr2 = {1,5,2,6,3,7,4,8};
	boolean ea= Arrays.equals(arr, arr1);//比较两个数组是否相等
	boolean ea1 = Arrays.equals(arr, arr2);//比较两个数组是否相等
	System.out.println(ea);//false
	System.out.println(ea1);//true
}
  • String toString(type[] a)

将数组转换成字符串。

public static void main(String[] args){
	int[] arr = {1,5,2,6,3,7,4,8};
	String as = Arrays.toString(arr);//将数组转换为字符串
	System.out.println(arr);//[I@15db9742
	System.out.println(as);//[1, 5, 2, 6, 3, 7, 4, 8]
}
  • void fill(type[] a,type value)

将数组的所有元素都赋值value。

public static void main(String[] args){
	int[] arr = {1,5,2,6,3,7,4,8};
	Arrays.fill(arr, 8);
	System.out.println(Arrays.toString(arr));//[8, 8, 8, 8, 8, 8, 8, 8]
}
  • void fill(type[] a,int fromIndex,int toIndex,type value)

对数组区间下标内的元素赋值value,包头不包尾。

public static void main(String[] args){
	int[] arr = {1,5,2,6,3,7,4,8};
	Arrays.fill(arr, 0, 2, 6);//对数组区间下标元素赋值(包头不包尾)
	System.out.println(Arrays.toString(arr));//[6, 6, 2, 6, 3, 7, 4, 8]
}
  • void sort(type[] a)

对数组元素进行排序。

public static void main(String[] args) {
	int[] arr = {1,5,2,6,3,7,4,8};
	Arrays.sort(arr);//使用工具类中的方法进行排序
	System.out.println(Arrays.toString(arr));//[1, 2, 3, 4, 5, 6, 7, 8]
}
  • void sort(type[] a, int fromIndex, int toIndex)

对数组指定下标区间的元素进行排序。

public static void main(String[] args) {
	int[] arr = {1,5,2,6,3,7,4,8};
	Arrays.sort(arr, 0, 3);//使用工具类中的方法进行区间排序
	System.out.println(Arrays.toString(arr));//[1, 2, 5, 6, 3, 7, 4, 8]
}

常见面试题

打印输出一个数组

public static void main(String[] args) {
	byte[] byteArray = {1,2,3,4,5};//byte类型数组
	short[] shortArray = {1,2,3,4,5};//short类型数组
	int[] intArray = {1,2,3,4,5};//int类型数组
	long[] longArray = {1,2,3,4,5};//long类型数组
	float[] floatArray = {1,2,3,4,5};//float类型数组
	double[] doubleArray = {1,2,3,4,5};//double类型数组
	String[] stringArray = {"1","2","3","4","5"};//Strig类型数组
	//  Arrays是一个工具类,java.util.Arrays,能够将byte、short、int、long、
	//  float、double、string类型的数组转换为string类型
	String strB = Arrays.toString(byteArray);
	String strS = Arrays.toString(shortArray);
	String strI = Arrays.toString(intArray);
	String strL = Arrays.toString(longArray);
	String strF = Arrays.toString(floatArray);
	String strD = Arrays.toString(doubleArray);
	String strStr = Arrays.toString(stringArray);
	System.out.println(intArray);//[I@15db9742
	System.out.println(strB);//[1, 2, 3, 4, 5]
	System.out.println(shortArray);//[S@6d06d69c
	System.out.println(strS);//[1, 2, 3, 4, 5]
	System.out.println(intArray);//[I@15db9742
	System.out.println(strI);//[1, 2, 3, 4, 5]
	System.out.println(longArray);//[J@7852e922
	System.out.println(strL);//[1, 2, 3, 4, 5]
	System.out.println(floatArray);//[F@4e25154f
	System.out.println(strF);//[1.0, 2.0, 3.0, 4.0, 5.0]
	System.out.println(doubleArray);//[D@70dea4e
	System.out.println(strD);//[1.0, 2.0, 3.0, 4.0, 5.0]
	System.out.println(stringArray);//[Ljava.lang.String;@5c647e05
	System.out.println(strStr);//[1, 2, 3, 4, 5]
}

判断输出的顺序

//面试题1
public static void main(String[] args){
	int i = 0;
	for (i++; i++ < 10; i++) {
		System.out.println(i+" ");//2 4 6 8 10
	}
	System.out.println(++i+" ");//13
	//循环中的布尔表达式i++ < 10可以理解成i<10;i=i+1,先用i用完再加1
	//第一次循环就是i声明的是0,for循环初始化(仅一次)后i=i+1=1,进行判断1<10,i= i+1=2,输出i是2,更新i=i+1=3
	//第二次循环i是3,进行判断3<10,i=i+1=4,输出i是4,更新i=i+1=5。
	//第三次循环i是5,进行判断5<10,i=i+1=6,输出i是6,更新i=i+1=7。
	//第四次循环i是7,进行判断7<10,i=i+1=8,输出i是8,更新i=i+1=9。
	//第五次循环i是9,进行判断9<10,i= i+1=10,输出i是10,更新i=i+1=11。
	//第六次循环i是11,进行判断11>10,不满足循环的判断条件,i=i+1=12,不再输出i,不再更新i。
	//循环结束,执行打印操作,此时i=12,++i=i+1=13。所以输出结果就是13。
}
//面试题2
static Boolean foo(char c){
	System.out.print(c);//ABDCBDCB
	return true;
}
public static void main(String[] args){
	int i = 0;
	for (foo('A');foo('B')&&(i<2);foo('C')) {
		i++;
		foo('D');
	}
}
// for循环结构的基础:
//		 for(初始化表达式(只执行一次);布尔表达式;更新表达式){
//			循环体
//		}
//		1、foo('A')就是初始化表达式;
//		2、foo('B')和(i<2)就是布尔表达式;
//		3、foo('C')就是更新表达式;
//		4、foo('D')就是循环体。

去重

list方式。需要判断数组的元素在不在list中存在。
set方式。set自带去重的功能。

public static void main(String[] args){
	//方式一:通过list
	int[] arr = {1,3,6,1,4,3,6,8,2,5,2,2};
	List<Integer> list = new ArrayList<Integer>();
	for (int i = 0; i < arr.length; i++) {
		if(!list.contains(arr[i])){
			list.add(arr[i]);
		}
	}
	System.out.println(list);//[1, 3, 6, 4, 8, 2, 5]
	
	//方式二:通过set
	int[] arr1 = {1,3,6,1,4,3,6,8,2,5,2,2};
	Set<Integer> set = new HashSet<Integer>();
	for (int i = 0; i < arr1.length; i++) {
		set.add(arr1[i]);
	}
	System.out.println(set);//[1, 2, 3, 4, 5, 6, 8]
}

数组中的最大值最小值

  • 冒泡排序方式,先排出顺序,再找最大值最小值。
public static void main(String[] args){
	int[] arr = {1,4,7,2,5,6,8,3};//正常数组
	int temp;
	for (int i = 0; i < arr.length-1; i++) {
		for (int j = 0; j < arr.length-i-1; j++) {
			if (arr[j] > arr[j+1]) {//从左往右由小到大排序
				temp = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = temp;
			}
		}
	}
	System.out.println(Arrays.toString(arr));//[1, 2, 3, 4, 5, 6, 7, 8]
	System.out.println(arr[arr.length-1]);//最大值是8
	System.out.println(arr[0]);//最小值是1
}
public static void main(String[] args){
	int[] arr1 = {1,3,6,1,4,3,6,8,2,5,2,2};//存在重复值的数组
	int temp1;
	for (int i = 0; i < arr1.length-1; i++) {
		for (int j = 0; j < arr1.length-i-1; j++) {
			if (arr1[j] > arr1[j+1]) {//从左往右由小到大排序
				temp1 = arr1[j];
				arr1[j] = arr1[j+1];
				arr1[j+1] = temp1;
			}
		}
	}
	System.out.println(Arrays.toString(arr1));//[1, 1, 2, 2, 2, 3, 3, 4, 5, 6, 6, 8]
	System.out.println(arr1[arr1.length-1]);//最大值是8
	System.out.println(arr1[0]);//最小值是1
}
  • 假设法方式,假设第一个是最大的,拿它去跟别的比。
public static void main(String[] args){
	int[] arr2 = {1,4,7,2,5,6,8,3};
	int max = arr2[0];//求最大值时,假设第一个最大
	int idx = 0;//最大值对应的元素下标
	for (int i = 0; i < arr2.length; i++) {
		if (arr2[i]>max) {
			max = arr2[i];
			idx = i;
		}
	}
	System.out.println(max);//8
	System.out.println(idx);//6
	int min = arr2[0];//求最小值时,假设第一个最小
	int idx2 = 0;//最小值对应的元素下标
	for (int i = 0; i < arr2.length; i++) {
		if (arr2[i]<min) {
			min = arr[i];
			idx2 = i;
		}
	}
	System.out.println(min);//1
	System.out.println(idx2);//0
}

删除数组中的元素

//删除数组中的元素
public static void main(String[] args) {
	String[] arr = {"1","2","3","4"};
	System.out.println(Arrays.toString(arr));//[1, 2, 3, 4]
	//Arrays.asList(arr)产生的list所持有的add、remove方法执行时会报错,因为这个Arrays.asList()方法返回的
	//是Arrays的内部类ArrayList,并不是我们通常使用的java.util.ArrayList,其实Arrays的arrayList
	//和java.util.ArrayList都继承了AbstractList,add、remove等方法在AbstractList中默认是
	//throw UnsupportedOperationException,并且不会做任何操作,java.util.ArrayList中重写了这些方法,
	//但是Arrays中的内部类ArrayList并没有重写这些方法。

	//方式一:使用Arrays工具类的asList()方法
	List<String> asList = Arrays.asList(arr);
	List<String> arrList = new ArrayList<String>(asList);
	arrList.remove(2);//根据下标删除
	arrList.remove("2");//根据元素删除
	System.out.println(arrList);//[1, 4]
	String[] arr1 = arrList.toArray(new String[1]);//将list转换为数组
	System.out.println(Arrays.toString(arr1));//[1, 4]
//删除数组中的元素
public static void main(String[] args) {
	String[] arr = {"1","2","3","4"};
	System.out.println(Arrays.toString(arr));//[1, 2, 3, 4]
	//Arrays.asList(arr)产生的list所持有的add、remove方法执行时会报错,因为这个Arrays.asList()方法返回的
	//是Arrays的内部类ArrayList,并不是我们通常使用的java.util.ArrayList,其实Arrays的arrayList
	//和java.util.ArrayList都继承了AbstractList,add、remove等方法在AbstractList中默认是
	//throw UnsupportedOperationException,并且不会做任何操作,java.util.ArrayList中重写了这些方法,
	//但是Arrays中的内部类ArrayList并没有重写这些方法。

	//方式二:
	List<String> strList = new ArrayList<String>();
	for (int i = 0; i < arr.length; i++) {
		strList.add(arr[i]);
	}
	strList.remove(1);//根据下标删除
	strList.remove("4");//根据元素删除
	System.out.println(strList);//[1, 3]
	String[] arr2 = strList.toArray(new String[1]);//list转数组
	System.out.println(Arrays.toString(arr2));//[1, 3]
//删除数组中的元素
public static void main(String[] args) {
	String[] arr = {"1","2","3","4"};
	System.out.println(Arrays.toString(arr));//[1, 2, 3, 4]

	//方式三:
	//把最后一个元素替代指定的元素,然后数组缩容。
	Scanner sc = new Scanner(System.in);
	System.out.println("请输入要删除第几个元素:");
	int n = sc.nextInt();
	sc.close();
	//把最后一个元素替代指定的元素
	arr[n-1] = arr[arr.length-1];
	//数组缩容
	arr = Arrays.copyOf(arr, arr.length-1);
	System.out.println(Arrays.toString(arr));
}
运行结果:
[1, 2, 3, 4]
请输入要删除第几个元素:
2   //(需要在这里键盘输入要删除那个元素,输入后点击enter键)
[1, 4, 3]

参考地址:
http://c.biancheng.net/view/5852.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值