数组
2024-04-09 18:00:07  阅读数 455

在Java开发中,处理相同类型的多个数据,可使用数组,即使用一个变量表示一组相同类型的数据

数组的概念

数组是具有相同数据类型,在内存中连续存储的多个变量的集合体

数组元素

构成数组的每个数据称为数组元素

数组的下标

元素在数组中的位置。用整数表示,从0开始,为数组的长度减一。

数组的大小

数组中元素的个数叫数组的大小,也叫数组的长度

数组的使用

  • 定义数组
  • 为数组元素分配元素
  • 数组元素的初始化
  • 使用数组

定义数组

定义数组的本质jvm申请内存,jvm将内存化分为几个区域,分为方法区,栈,堆。不同区域储存不同类别的内存。定义数组时,jvm(虚拟机)将数组名称储存在栈中,栈是先进后出觉得数据结构,因此数组名称在栈中,也叫线性表。

定义数组两种代码

int array[];

//int []array;

内存结构:数组名称被分配在栈中,数组名为引用类型,默认值为null

提示:内存地址标号由windos(操作系统),分配通常用十六进制表示,以Ox为开头

为数组元素分配内存

语法格式:

array=new int[5];

数组名=new 元素类型[数组大小]

定义数组和分配内存可以合并写出

列如:

int array =new int[5]

为数组元素分配内存

以array=new int[5]为例:

  • new 为分配内存的意思,程序向jvm申请连续的,可以存放五个int类型变量,申请的内存分配在堆中。

  • =表示将new申请的内存空间的首地址赋值给数组名array,array的值由默认值null,变为申请的五个内存单元的首个的地址编号图中为OxAA01

  • 数组储存数据时,数组元素实际是储存在jvm在堆中分配的内存单元,即数据存储在:array[0],array[1],array[2],array[3],array[4]。

  • 数组元素是相同类型的,即数组的类型与数组的元素类型相同。

  • int 类型的数组是引用类型,int类型的数组元素是基本类型。

数组元素初始化

数组声明并为数组元素分配内存后,必须为数组元素初始化后,才能使用数组,如果没有为数组元素初始话,那么数组元素是有默认值的如下:

  • 数组元素是byte,short,int,long:0

  • 数组元素是float,double:0.0

  • 数组元素是char型:0或’\u0000’,而非’0’

  • 数组元素是boolean型:false

  • 数组元素是引用数据类型:null

定义数组,分配内存,数组元素初始话可以一步进行如下:

int array[]=new int[]{1,2,3,4,5}

int array[]={1,2,3,4,5}

注意:int array[]=new int[5]{1,2,3,5,4}会编译错误

数组的使用

使用数组通常是求数组的最大值,最小值,总和,平均值,遍历数组元素,数组元素排序,数组中元素的数量的操作等操作。

最大值,最小值,平均值,求和

public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int []score = new int[5];
        //成绩初始化
        for (int i = 0; i < score.length; i++) {
            System.out.println("请输入第"+(i+1)+"个学生的成绩");
            score[i]= s.nextInt();
        }
        //求最高分,求最低分
        int max  = score[0];
        int min = score[0];
        for (int i = 1; i < score.length; i++) {
            if(max<score[i]){
                max = score[i];
            }
            if(min>score[i]){
                min = score[i];
            }
        }
        System.out.println("最高分为"+max);
        System.out.println("最低分为"+min);
        //总分
        int sum = 0;
        for (int i = 0; i < score.length; i++) {
            sum += score[i];
        }
        System.out.println("班级总分:"+sum);
        System.out.println("班级平均分"+sum/score.length);
    }

80000个随机数的排序操作

冒泡排序

冒泡排序
 public static void main(String[] args) {
        //冒泡排序
        int score[] = new int[80000];
        Random random = new Random();
        for (int i = 0; i < score.length; i++) {
            score[i] = random.nextInt(80000);
        }
        long start = System.currentTimeMillis();

        for (int i = 0; i < score.length-1; i++) {
            for (int j = 0; j < score.length-i-1; j++) {
                if(score[j]>score[j+1]){
                    int tmp = score[j];
                    score[j]=score[j+1];
                    score[j+1]= tmp;
                }
            }
        }

        long end = System.currentTimeMillis();
        System.out.println(end-start);

大约耗时9000毫秒

选择排序

选择排序
public static void main(String[] args) {
        //选择排序
        int[] arr = new int[80000];
        Random r = new Random();
        for (int i = 0; i < arr.length; i++) {
            arr[i] = r.nextInt(80000);
        }
        long start  = System.currentTimeMillis();
        for (int i = 0; i < arr.length-1; i++) {//每次循环都会找出最小的数
            int minIndex = i;//记录最小数的下标
            int min = arr[i];//记录最小数
            for(int j = i+1; j < arr.length; j++){//每次循环都会找出最小的数
                if (arr[j] < min){//如果当前数比最小数小,则更新最小数
                    min = arr[j];//更新最小数
                    minIndex = j;//更新最小数的下标
                }
            }
            int tmp = arr[i];
            arr[i] = arr[minIndex];//将最小数放到最前面
            arr[minIndex] = tmp;
        }
        long end  = System.currentTimeMillis();
        System.out.println(end-start);
        System.out.println(Arrays.toString(arr));
    }

大约耗时2000毫秒;

插入排序

插入排序
public static void main(String[] args) {
        //插入排序
        int[] arr = new int[80000];
        for (int i = 0; i < 80000; i++) {
            arr[i] = (int)(Math.random() * 80000);
        }
        long start = System.currentTimeMillis();
 
        for (int i = 1; i < arr.length; i++) {
            int j = i;
            while (j > 0){
                if (arr[j] < arr[j-1]){
                    int temp ;
                    temp = arr[j];
                    arr[j] = arr[j-1];
                    arr[j-1] = temp;
                    //System.out.println(Arrays.toString(arr));
                    j--;
                }else {
                    break;
                }
            }
        }
        long end = System.currentTimeMillis();
        System.out.println(end -start);
    }

耗时大约700毫秒;

快速排序

快速排序
public static void main(String[] args){
        //快排
        int[] arr = new int[80000];
        for (int i = 0; i < 80000; i++) {
            arr[i] = (int)(Math.random() * 800000);
        }

        //打印开始排序时的时间
        long s = System.currentTimeMillis();
        quickSort(arr,0,arr.length-1);
        //打印排序结束时的时间
        long e = System.currentTimeMillis();
        System.out.println(e-s);
    }

    public static void quickSort(int[] arr,int first,int last){
        if (first >= last) {
            return;
        }

        int low = first;
        int high = last;
        //如果mid_value = arr[last]的话,下面的两个内部while循环就要换一下顺序
        int mid_value = arr[first];


        while (low < high){
            while (low < high && arr[high] >= mid_value){
                high-=1;
            }
            arr[low] = arr[high];

            while (low < high && arr[low] < mid_value){
                low +=1;
            }
            arr[high] = arr[low];
        }
        arr[high] = mid_value;
        //递归对左右两边的数据排序
        quickSort(arr,first,low-1);
        quickSort(arr,low+1,last);
    }

排序时间极快仅仅需要20毫秒左右;
80000个数据排序冒泡约需9000毫秒,而快速排序仅仅只需约20毫秒,可见差距之大

其他排序方法

  • 希尔排序
  • 归并排序
  • 基数排序
  • 堆排序
  • 计数排序
  • 桶排序
  • 二叉树排序等

数组某个元素的查找

二分查找

折半查找法
public static void main(String[] args){
        int num[] = {3,9,12,48,67};
        int index = binarySearch(num,9);
        System.out.println(index);
    }

    public static int binarySearch(int[] srcArray, int des) {

        int start = 0;
        int end = srcArray.length - 1;
        //确保不会出现重复查找,越界
        while (start <= end) {
            //计算出中间索引值
            int middle = (end + start)>>>1 ;//防止溢出
            if (des == srcArray[middle]) {
                return middle;
                //判断下限
            } else if (des < srcArray[middle]) {
                end = middle - 1;
                //判断上限
            } else {
                start = middle + 1;
            }
        }
        //若没有,则返回-1
        return -1;
    }

数组的工具类java.util.Array

比较两个数组是否相等

public static void main(String[] args) {
        int []arr1 = {10,50,40,30};
        int []arr2 = {10,50,40,30};
        int []arr3 = {60,50,85};
        System.out.println(Arrays.equals(arr1, arr2));//判断arr1与arr2的长度及元素是否相等
        System.out.println(Arrays.equals(arr1, arr3));//判断arr1与arr3的长度及元素是否相等
    }

对数组元素进行升序排序

数组指定小标范围排序

 public static void main(String[] args){
        int []arr1 = {10,50,40,30,89,67,4,678};
        Arrays.sort(arr1,3,arr1.length-1);
        for (int i = 0; i < arr1.length; i++) {
            System.out.println(arr1[i]);
        }
    }

将数组转换成字符串

public static void main(String[] args){
        int []arr1 = {10,50,40,30,89,67,4,678};
        Arrays.sort(arr1);
        System.out.println( Arrays.toString(arr1));
    }

将数组所有元素赋值为相同的值

public static void main(String[] args){
        int []arr1 = {10,50,40,30,89,67,4,678};
        Arrays.fill(arr1,30);
        System.out.println( Arrays.toString(arr1));
    }

将数组赋值成一个长度为设定值的新数组

 public static void main(String[] args){
        int []arr1 = new int[] {10,50,40,30 };

        //将arr1复制成长度为3的新数组arr2
        int []arr2 = Arrays.copyOf(arr1,3);
        System.out.println(Arrays.toString(arr2));

    }

查询元素在数组中的下标

public static void main(String[] args){
       int []arr = new int[] {10,50,40,30 };
       Arrays.sort(arr);//排序后 10 30 40  50 90
       
       int index = Arrays.binarySearch(arr, 10);
       System.out.println(index);

       index = Arrays.binarySearch(arr, 0);
       System.out.println(index);

       index = Arrays.binarySearch(arr, 45);
       System.out.println(index);

       index = Arrays.binarySearch(arr, 90);
       System.out.println(index);
   }

二维数据

Java中定义和操作多维数组的语法与一维数组类似。在实际应用中,三维及其以上的数组使用很少,主要使用二维数组。使用二维数组的步骤如下:

  • 定义数组
  • 为数组元素分配内存
  • 数组元素的初始化
  • 使用数组

定义二维数组

定义二维数组的语法规则如下:

  • 数据类型[][] 数组名;·
  • 数据类型 数组名[][];
int [][]s;

为二维数组分配内存

int [][]s;
s=new int [3][3];

二维数组实际上是一个一维数组,这个一维数组的每个元素又是一个一维数组

二维数组初始化

int [][]scores=new int[][]{
{1,1,1},
{1,1,1},
{1,1,1}
};
int [][]scores={
{1,1,1},
{1,1,1},
{1,1,1}
};

二维数组的遍历

步骤如下:

  • 初始化二维数组。
  • 定义保存总成绩的变量。
  • 使用双重for循环遍历二维数组。
public static void main(String[] args) {
        /*
         * 定义3个班级,第一个班级2名学生,第二个班级3名学生,第三个班级2名学生
         * 初始化3个班级所有的学生成绩*/
        int[][] scores = {
                {67, 75},
                {78, 82, 93},
                {71, 72}
        };
        int total;
        for (int i = 0; i < scores.length; i++) {
            String str = (i + 1) + "班";
            total = 0;
            for (int j = 0; j < scores[i].length; j++) {
                total += scores[i][j];
            }
            System.out.println(str + "总成绩" + total);
        }
    }