数组概述
- 数组,就可以理解为多个数据的组合
- 是程序中的容器:数组、集合框架(List、Set、Map)
- 数组存储的数据的特点:依次紧密排序的,有序的,可以重复的
- 此时的数组、集合框架都是在内存中对多个数据存储
- 数组的其他特点:一旦初始化,其长度就是确定的、不可更改的
一维数组的使用(重要)
-
数组的声明和初始化
int [] arr = new int[3];
int [] arr1 = new int[] {1,2,3}; -
调用数组指定元素:使用角标、索引、index
-
数组的属性:length表示数组的长度
-
数组的遍历
-
数组元素的默认初始化值
1)整型数组元素初始化值:0
2)浮点型数组元素初始化值:0.0
3)字符型数组元素初始化:0
4)boolean型数组元素初始化:false
- 引用数据类型数组元素默认值:null
- 一维数组的内存解析
前提;在main()中声明变量:int [] arr = new int []{1,2,3};
虚拟机栈:main()作为一个栈帧,压入栈空间中。在main()栈帧中,存储着arr变量。arr记录着数组实体的首地址值
堆:数组实体存储在堆空间中
二维数组的使用(难点)
- 二维数组:一维数组的元素,又是一个唯一数组,则构成二维数组
- 调用数组的指定元素
- 数组的属性:length,表示数组的长度
- 数组的遍历
- 数组元素默认初始化值
- 二维数组的内存解析
1)外层元素,默认存储地址值
2)内层元素:默认与一维数组元素的不同类型的默认值规定相同
数组的常用算法
- 数值型数组的特征值计算:最大值、最小值、总和、平均值等
- 数组元素的赋值。比如:杨辉三角
package ArrayTest;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* 【数组的常见算法1】
* 1、数值型数组特征值统计
* 这里的特征涉及到:平均值、最大值、最小值、总和等
*
* 2、数组的元素赋值
*/
public class TwoArrayOpeExer {
/**
* 案例:定义一个int类型的数组,包含10个元素,分别赋值一些随机整数,然后求出所有元素的最大值、最小值、总和,平均值,并输出来
* 要求:所有随机数都是两位数:[10,99]
* 提示:求[a,b]范围内的随机数:(int)(Math.random(b-a+1))+a;
*/
public static void main(String[] args) {
//1.动态初始化方式创建数组
int [] arr = new int[10];
//2.通过循环给数组元素赋值
for(int i=0;i< arr.length;i++){
arr[i] = (int)(Math.random()*(99-10+1))+10;
System.out.println(arr[i]);
}
//3.求最大值
int max = arr[0];
for(int i1=0;i1<arr.length;i1++){
if(max<arr[i1]){
max = arr[i1];
}
}
System.out.println("最大值为:"+max);
//4.求最小值
int min = arr[0];
for(int i2=0;i2< arr.length;i2++){
if(min>arr[i2]){
min=arr[i2];
}
}
System.out.println("最小值为:"+min);
//3.3 求总和、平均值
int sum=0;
for(int i=0;i< arr.length;i++){
sum+=arr[i];
}
System.out.println("总和为"+sum);
int avg = sum/arr.length;
System.out.println("均值为"+avg);
/**
* 案例:评委打分
* 分析以下需求,并用代码实现
* (1)在编程竞技中,有10位评委为参赛的选手打分,分数分别为:5,4,6,8,9,0,1,2,7,3
* (2)求选手的最后得分(去掉一个最高分和一个最低分后,其余8位评委打分的平均值)
*/
int arr1[] = new int[10];
//(0,10)
int sum1=0;
int max1=arr1[0];
int min1=arr1[0];
for(int i=0;i< arr1.length;i++){
int score = (int)(Math.random()*11);
arr1[i]=score;
sum1+=arr1[i];
}
for(int i =0;i<arr1.length;i++){
if(arr1[i]>max1){
max1=arr1[i];
}
if(arr1[i]<min1){
min1=arr1[i];
}
}
double result = (double) (sum1-min1-max1)/ (arr1.length-2);
System.out.println(result);
/**
* 使用二维数组打印一个10行杨辉三角。
* 提示:
* 1
* 1 1
* 1 2 1
* 1 3 3 1
* 1 4 6 4 1
*1、第一行有1个元素,第n行有n个元素
*2、每一行的第一个元素和最后一个元素都是1
* 3、从第三行开始,对于非第一个元素和最后一个元素。即:
* yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];
*
*/
//1.创建二维数组
int [][] arr2 = new int[10][];
//2.使用循环结构初始化外层数组元素
for(int i=0;i< arr2.length;i++) {
arr2[i] = new int[i + 1];
//3.给数组的元素赋值
//3.1给数组每行的首末元素赋值为1
arr2[i][0] = 1;
arr2[i][i] = 1;
//3.2给数组每行的非首末元素赋值
for (int j = 1; j < arr2[i].length - 1; j++) {
arr2[i][j] = arr2[i - 1][j - 1] + arr2[i - 1][j];
}
}
//遍历二维数组
for(int i=0;i<arr2.length;i++){
for(int j=0;j<arr2[i].length;j++){
System.out.print(arr2[i][j]+"\t");
}
System.out.println();
}
/**
* 创建一个长度为6的int型数组,要求数组元素的值都在1-30之间,且都是随机赋值。同时,要求元素的值各不相同
*/
Random random = new Random();
List<Integer> list = new ArrayList<>();
while(list.size()<6){
int num = random.nextInt(30)+1;
if(!list.contains(num)){
list.add(num);
}
}
System.out.println(list);
/**
* 案例:遍历扑克牌
* 提示:使用两个字符串数组,分别保存花色和点数,再用一个字符串
* Stirng [] hua = {"黑桃","红桃","梅花","方片"}
* String [] dian = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"}
*/
String [] hua = {"黑桃","红桃","梅花","方片"};
String [] dian = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
String result1 [] = new String[hua.length* dian.length];
int k=0;
for(int i=0;i< hua.length;i++){
for(int j=0;j< dian.length;j++){
result1[k++]=hua[i]+dian[j];
}
}
for(int i=0;i<result1.length;i++){
System.out.print(result1[i]+ " ");
if(i%13 == 12){
System.out.println();
}
}
}
}
- 数组的复制、赋值、反转、扩容、缩容
- 数组的查找
线性查找、二分法查找(前提:数组有序) - 数组的排序
冒泡排序:最简单
快速排序:最常用
package ArrayTest;
public class ArrayExpr2 {
/**
* 【数组的常见算法2】
* 1、数组的扩容与缩容
* 2、数组元素的查找
* 顺序查找:
* 优点:算法简单
* 缺点:执行效率低,执行的复杂度O(N)
* 二分查找:
* 优点:执行效率高,执行时间复杂度O(logN)
* 缺点:算法相对于顺序查找难一点;数据必须是有序的
*
* 3、数组的排序:通常来说,排序的目的是快速查找
* 衡量排序算法的优势:
* 时间复杂度:分析关键字比较次数和记录的移动次数
* 空间复杂度:分析排序算法需要多少辅助内存
* 稳定性:若两个记录A和B的关键字值相等,但排序后A\B的先后顺序保持不变,则称为这种顺序算法是稳定的。
* 冒泡排序:时间复杂度(O(N^2))
*
*
*
* 快速排序:时间复杂度(O(nlogn))
*
*
*/
public static void main(String[] args) {
/**
* 案例1:数组的扩容
* 现有数组 int [] arr = new int[]{1,2,3,4,5};
* 先将数组的长度扩容1倍,并将10,20,30三个数据添加到arr数组中
*/
int [] arr = new int[]{1,2,3,4,5};
//扩容1倍容量
int [] newarr = new int[arr.length*2];
//将原有数组中的元素赋值到新的数组中
for(int i=0;i<arr.length;i++){
newarr[i]=arr[i];
}
// 将10、20、30三个数据添加到数组中
newarr[arr.length]=10;
newarr[arr.length+1]=20;
newarr[arr.length+2]=30;
//将新的数组的地址赋值给原有的数组变量
arr = newarr;
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+"\t");
}
System.out.println();
/**
* 案例2:数组的缩容
* 现有数组 int[] arr={1,2,3,4,5,6,7}.现需删除数组中索引为4的元素
*/
int arr2 [] = new int[]{1,2,3,4,5,6,7};
int deleteIndex = 4;
int newarr2 [] = new int[arr2.length-1];
for(int i=0;i<deleteIndex;i++){
newarr2[i] = arr2[i];
}
for(int i=deleteIndex;i<arr2.length-1;i++){
newarr2[i]=arr2[i+1];
}
arr2 = newarr2;
for(int i=0;i<arr2.length;i++){
System.out.print(arr2[i]+"\t");
}
System.out.println();
/**
*线性查找
* 定义数组:int [] arr3 = new int[]{34,54,3,2,65,7,34,5,76,34,67};
* 查找元素5是否在上述数组中出现过?如果出现,输出对应的索引值
*/
boolean flag = true;
int [] arr3 = new int[]{34,54,3,2,65,7,34,5,76,34,67};
int target =5;
for(int i=0;i<arr3.length;i++){
if(target==arr3[i]){
System.out.println(i);
flag=false;
break;
}
}
if(flag){
System.out.println("不好意思,没有找到此元素");
}
/**
* 二分查找
* 定义数组:int arr4 [] = new int[]{2,4,5,8,12,15,19,26,37,49,51,66,89,100};
* 查找元素5是否在上述数组中出现过?如果出现,输出对应的索引值。
*
* 二分查找步骤:
* 1、设定头部边界下标和尾部边界下标初始值 head=0,end=arr.length-1
* 2.如果head<=end,计算中间元素下标mid=(head+end)/2
* 如果value=arr[mid], true 找到了
* 如果value>arr[mid] ,true 修改左边边界 head=mid+1
* 如果value<arr[mid], true 修改右边边界 end=min-1
*/
int arr4 [] = new int[]{2,4,5,8,12,15,19,26,37,49,51,66,89,100};
int head=0;
int end=arr4.length-1;
int target1 = 100;
boolean is_flag=false;
while(head<=end){
int mid =(head+end)/2;
if(target1==arr4[mid]){
System.out.println("找到了"+target1+",对应的位置为,"+mid);
is_flag=true;
break;
}else if(target1>arr4[mid]){
head = mid+1;
}else{
end = mid-1;
}
}
if(!is_flag){
System.out.println("不好意思,未找到");
}
/**
* 使用冒泡排序、实现整型数组元素的排序操作
* 比如:int arr5[] = new int[]{34,54,3,2,65,7,34,5,76,34,67}
*/
int arr5[] = new int[]{34,54,3,2,65,7,34,5,76,34,67};
//遍历
for(int i=0;i<arr5.length;i++){
System.out.print(arr5[i]+"\t");
}
//冒泡排序,实现数组元素从小到大排列
for(int j=0;j<arr5.length-1;j++){
for(int i=0;i<arr.length-j;i++){
if(arr5[i]>arr5[i+1]){
//交换arr5[i] 和 arr5[i+1]
int temp = arr5[i];
arr5[i] = arr5[i+1];
arr5[i+1]=temp;
}
}
}
System.out.println();
for(int i=0;i<arr5.length;i++){
System.out.print(arr5[i]+"\t");
}
/**
*
*/
}
}
Araays工具类的使用
toSring()/sort()/binarySearch()
数组中的常见异常
- ArrayIndexOutBoundsException(数组角标越界异常)
- NullPointerException(空指针异常)
package ArrayTest;
/**
* 数组的使用中常见异常小结
* >数组角标越界异常:ArrayIndexOutBoundsException
* >空指针异常:NullPointerException
*
*/
import java.util.Arrays;
public class ArraysTest {
/**
* 数组工具类Arrays的使用(熟悉)
* 1、Arrays类所在位置:处在java.util包下
* 2、作用:
* java.util.Arrays类即为操作数组的工具类,包含了用来操作数组(比如排序和搜索) 的各种方法。
*/
public static void main(String[] args) {
//1.boolean equals(int[] a,int [] b);比较两个数组的元素是否依次相等
int [] arr1 = new int[]{1,2,3,4,5};
int [] arr2 = new int[]{1,2,3,4,5};
boolean isEqual = Arrays.equals(arr1,arr2);
System.out.println(isEqual);
//2.String toString(int[] a):输出数组元素信息
String result = Arrays.toString(arr1);
System.out.println(result);
//3.void fill(int[] a.int val):将制定值填充到数组中
Arrays.fill(arr1,10);
System.out.println(Arrays.toString(arr1));
//4.void sort(int []a):使用快速跑徐算法实现的排序
int [] arr3 = new int[]{34,54,3,2,65,7,34,5,76,34,67};
Arrays.sort(arr3);
System.out.println(Arrays.toString(arr3));
//5. int binarySearch(int [] a,int key);二分查找
//当返回的数值为复数,表示没找到
//使用前提:当前数组必须是有序的
int index = Arrays.binarySearch(arr3,5);
if(index>0){
System.out.println("找到了,索引位置为:"+index);
}else{
System.out.println("未找到");
}
//空指针异常
// int [] arr4 = new int [10];
// arr4=null;
// System.out.println(arr4[0]);
//情况二
int [][] arr5 = new int [3][];
System.out.println(arr5[0][1]);
}
}
企业真题
-
数组有没有length()这个方法?String有没有length()这个方法?
数组没有length(),是length属性
String有length() -
有数组int [] arr,用java代码将数组元素顺序颠倒
-
为什么数组要从0开始编号,而不是1
数组的索引表示数据元素距离首地址的偏移量。因为第一个元素的地址与首地址相同,所以偏移量就是0.所以从0开始 -
数组有什么排序的方式,手写一下
冒泡 -
常见排序算法,说一下快排的过程,时间复杂度?
-
二分算法实现数组的查找
-
怎么求数组的最大子序列和