Java数组

数组的概述

在Java中,数组是一种效率最高的存储和随机访问对象引用序列的方式。数组就是一个简单的线性序列,这使得元素访问非常快速。但是为这种速度所付出代价是数组对象大小被固定,并且在其声明周期中不可改变。数组内的元素既可以是基本数据类型,也可以是引用数据类型。区别在于对象数据保存的是引用,基本类型数组直接保存基本类型的值。

  1. java语言中的数组是一种引用数据类型,不属于基本数据类型,数组的父类是Object。
  2. 数组实际上是一个容器,可以同时容纳多个元素(数组是一个数据的集合)字面意思:“一组数据”
  3. 数组当中可以储存“基本数据类型”的数据,也可以储存“引用数据类型”的数据
  4. 数组因为是引用类型,所以数组对象是堆内存当中(数组是存储在堆当中的)。
  5. 数组当中如果存储的是“java对象”的话,实际上存储的是对象的“引用地址”
  6. 数组一旦创建,在java中规定,长度不可变。(数组长度不可变)
  7. 数组的分类: 一维数组、二维数组、三维数组、多维数组…(一维数组较多,二维数组偶尔使用)
  8. 所有的数组对象都有length属性(java自带的),用来获取数组中元素的个数。
  9. java中的数组要求数组中元素的类型统一,比如int类型数组只能存储int类型,String类型数组只能存储String类型。
  10. 数组在内存方面存储的时候,数组中的元素内存地址(存储的每一个元素都是有规则的挨着排列的)是连续的,内存地址连续这是数组内存元素的特点,数组实际上是一种简单的数据结构。
  11. 所有的数组都是拿“第一个小方框的内存地址”作为整个数组对象的内存地址。(数组中首元素的内存地址作为整个数组对象的内存地址)
  12. 对于数组来说,实际上只能储存java对象的“内存地址”,数组中存储的每个元素是"引用".

优点:
查询/查找/检索某个下标上的元素时效率极高,可以说时查询效率最高的一个数据结构。

为什么检索高??
1.每一个元素的内存地址在空间存储上是连续的。

2.每一个元素类型相同,所以占用空间大小一样。

3.知道第一个元素内存地址,知道每一个元素占用空间的大小,又知道下标,所以通过一个数学表达式就可以计算出某个下标上元素的内存地址,通过内存地址定位元素,所以数组的检索效率是最高的。(int类型的数据占用4个字节)

缺点:

1.由于为了保证数组中每个元素的内存地址连续,所以在数组上随机删除或者增加元素的时候,效率较低,因为随机增删元素会涉及到后面元素统一向前或者向后位移的操作。

2.数组不能存储大数据量,因为很难在内存空间找到一块特别大的连续的内存空间。

数组的定义方式

使用new操作符来创建数组,语法如下:

arrayRefVar = new dataType[arraySize];

上面的语法语句做了两件事:

  • 一、使用 dataType[arraySize] 创建了一个数组。
  • 二、把新创建的数组的引用赋值给变量 arrayRefVar。

数组变量的声明,和创建数组可以用一条语句完成,如下所示:

dataType[] arrayRefVar = new dataType[arraySize];

另外,你还可以使用如下的方式创建数组。

dataType[] arrayRefVar = {value0, value1, ..., valuek};

数组的元素是通过索引访问的。数组索引从 0 开始,所以索引值从 0 到 arrayRefVar.length-1。

定义一个数组类型的变量,使用数组类型“类型[]”,例如,int[]。和单个基本类型变量不同,数组变量初始化必须使用new int[5]表示创建一个可容纳5个int元素的数组。

Java的数组有几个特点:

  • 数组所有元素初始化为默认值,整型都是0,浮点型是0.0,布尔型是false
  • 数组一旦创建后,大小就不可改变。

要访问数组中的某一个元素,需要使用索引。数组索引从0开始,例如,5个元素的数组,索引范围是0~4

可以修改数组中的某一个元素,使用赋值语句,例如,ns[1] = 79;

可以用数组变量.length获取数组大小

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-il5kI5j2-1660981621008)(D:\Typora\img\image-20220815100037545.png)]

常用的数组操作

遍历

通过for循环就可以遍历数组。因为数组的每个元素都可以通过索引来访问,因此,使用标准的for循环可以完成一个数组的遍历:

public class Main {
    public static void main(String[] args) {
        int[] ns = { 1, 4, 9, 16, 25 };
        for (int i=0; i<ns.length; i++) {
            int n = ns[i];
            System.out.println(n);
        }
    }
}

为了实现for循环遍历,初始条件为i=0,因为索引总是从0开始,继续循环的条件为i<ns.length,因为当i=ns.length时,i已经超出了索引范围(索引范围是0 ~ ns.length-1),每次循环后,i++

第二种方式是使用for each循环,直接迭代数组的每个元素:

public class Main {
    public static void main(String[] args) {
        int[] ns = { 1, 4, 9, 16, 25 };
        for (int n : ns) {
            System.out.println(n);
        }
    }
}

for (int n : ns)循环中,变量n直接拿到ns数组的元素,而不是索引。

显然for each循环更加简洁。但是,for each循环无法拿到数组的索引

排序

常用的排序算法有冒泡排序、插入排序和快速排序等。

冒泡排序

使用冒泡排序算法对一个整型数组从小到大进行排序:

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] ns = { 28, 12, 89, 73, 65, 18, 96, 50, 8, 36 };
        // 排序前:
        System.out.println(Arrays.toString(ns));
        for (int i = 0; i < ns.length - 1; i++) {
            for (int j = 0; j < ns.length - i - 1; j++) {
                if (ns[j] > ns[j+1]) {
                    // 交换ns[j]和ns[j+1]:
                    int tmp = ns[j];
                    ns[j] = ns[j+1];
                    ns[j+1] = tmp;
                }
            }
        }
        // 排序后:
        System.out.println(Arrays.toString(ns));
    }
}

冒泡排序的特点是,每一轮循环后,最大的一个数被交换到末尾,因此,下一轮循环就可以“刨除”最后的数,每一轮循环都比上一轮循环的结束位置靠前一位。

选择排序

import java.util.Arrays;

public class Array_01 {
    public static void main(String[] args) {
//        bubblesort();
        selectsort();
//        insertSort();
//        countSort();
    }
    private static void selectsort() {
        int[] arr = {23, 45, 6, 7, 99, 78, 29};
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[i] > arr[j]) {
                    swap(arr, i, j);
                }

            }
//            System.out.println(Arrays.toString(arr));
        }
        System.out.println(Arrays.toString(arr));
    }
    
     public static void swap(int[] arr, int i, int j) {
        arr[i] = arr[i] + arr[j];
        arr[j] = arr[i] - arr[j];
        arr[i] = arr[i] - arr[j];
    }
   }

插入排序

import java.util.Arrays;

public class Array_01 {
    public static void main(String[] args) {
//        bubblesort();
//        selectsort();
        insertSort();
//        countSort();
    }
    private static void insertSort() {
        int[] arr = {34, 56, 8, 12, 3, 45, 98};
        int e;
        int j;
        for (int i = 1; i < arr.length; i++) {
            e = arr[i];
            for (j = i; j > 0 && arr[j - 1] > e; j--) {
                arr[j] = arr[j - 1];
            }
            arr[j] = e;
            System.out.println(Arrays.toString(arr));
        }
//        System.out.println(Arrays.toString(arr));

    }
    
     public static void swap(int[] arr, int i, int j) {
        arr[i] = arr[i] + arr[j];
        arr[j] = arr[i] - arr[j];
        arr[i] = arr[i] - arr[j];
    }
   }

计数排序

import java.util.Arrays;

public class Array_01 {
    public static void main(String[] args) {
//        bubblesort();
//        selectsort();
//        insertSort();
        countSort();
    }
	private static void countSort() {
        int[] arr = {3, 67, 3, 5, 46, 89, 1, 47};
        int min = arr[0];
        int max = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
            if (arr[i] < min) {
                min = arr[i];
            }
        }
        int[] nums = new int[max - min + 1];
        int offset = min;
        for (int i = 0; i < arr.length; i++) {
            nums[arr[i] - offset]++;
        }
        int index = 0;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] != 0) {
                for (int j = 0; j < nums[i]; j++) {
                    arr[index++] = i + offset;
                }
            }
        }
        System.out.println(Arrays.toString(nums));
        System.out.println(Arrays.toString(arr));
    }
    
     public static void swap(int[] arr, int i, int j) {
        arr[i] = arr[i] + arr[j];
        arr[j] = arr[i] - arr[j];
        arr[i] = arr[i] - arr[j];
    }
   }

查找

顺序查找和二分法查找

public class Array_03 {
    public static void main(String[] args) {
        linearSearch();
        binarySearch();

    }
    private static void linearSearch(){
        int[] arr = {6,9,1,5,2,3,8,4,7};
        int key = 8;
        int index = -1;
        for (int i = 0; i <arr.length; i++){
            if (arr[i] == key){
                index = i;
                break;
            }
        }
        System.out.println(index);
    }

    private static void binarySearch(){
        int[] arr = {6,9,1,5,2,3,8,4,7};
        int key = 8;
        int min_index = 0;
        int max_index = arr.length - 1;
        int mid_index = (min_index + max_index)/ 2 ;
        while (arr[mid_index] != key) {
            if (key < arr[mid_index]) {
                max_index = mid_index - 1;
            }
            if (arr[mid_index] < key) {
                min_index = mid_index -1;
                
            }
            if (min_index>max_index){
                mid_index = -1;
                break;
            }
            mid_index = (min_index+max_index)/2;
        }
        System.out.println(mid_index);

    }
}

二维数组

二维数组就是数组的数组。定义一个二维数组如下:

public class Main {
    public static void main(String[] args) {
        int[][] ns = {
            { 1, 2, 3, 4 },
            { 5, 6, 7, 8 },
            { 9, 10, 11, 12 }
        };
        System.out.println(ns.length); // 3
    }
}

访问二维数组的某个元素需要使用array[row][col],例如:

System.out.println(ns[1][2]); // 7

要打印一个二维数组,可以使用两层嵌套的for循环:

for (int[] arr : ns) {
    for (int n : arr) {
        System.out.print(n);
        System.out.print(', ');
    }
    System.out.println();
}

或者使用Java标准库的Arrays.deepToString()

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[][] ns = {
            { 1, 2, 3, 4 },
            { 5, 6, 7, 8 },
            { 9, 10, 11, 12 }
        };
        System.out.println(Arrays.deepToString(ns));
    }
}

Arrays数组工具类

java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。

具有以下功能:

  • 给数组赋值:通过 fill 方法。
  • 对数组排序:通过 sort 方法,按升序。
  • 比较数组:通过 equals 方法比较数组中元素值是否相等。
  • 查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作。

具体说明请查看下表:

序号方法和说明
1public static int binarySearch(Object[] a, Object key) 用二分查找算法在给定数组中搜索给定值的对象(Byte,Int,double等)。数组在调用前必须排序好的。如果查找值包含在数组中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。
2public static boolean equals(long[] a, long[] a2) 如果两个指定的 long 型数组彼此相等,则返回 true。如果两个数组包含相同数量的元素,并且两个数组中的所有相应元素对都是相等的,则认为这两个数组是相等的。换句话说,如果两个数组以相同顺序包含相同的元素,则两个数组是相等的。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。
3public static void fill(int[] a, int val) 将指定的 int 值分配给指定 int 型数组指定范围中的每个元素。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。
4public static void sort(Object[] a) 对指定对象数组根据其元素的自然顺序进行升序排列。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。
5public static int[] copyOf(int[] original, int[] newLength ) 复制指定的数组,截取或用0填充,以使副本具有指定的长度
6public static toString(int[] a) 返回指定数组内容的字符串表现形式
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_59138290

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值