栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java数组

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java数组

目录

一维数组

二维数组

数组的排序及查找

冒泡排序

选择排序

数组元素一个一个查找

二分法查找

数组工具类


数组:
1、Java语言中的数组是一种引用数据类型。不属于基本数据类型,数组的父类是Object。

2、数组实际上是一个容器,可以容纳多个元素。(数组是一个数据的集合。)
      数组:字面意思是“一组数据”。

3、数组当中可以存储“基本数据类型”的数据,也可以存储“引用数据类型”的数据。

4、数组因为是引用数据类型,所以数组对象是堆内存当中。(数组是存储在堆内存中的。)

5、数组当中如果存储的是“java对象”的话,实际上存储的是对象的“引用(内存地址)”,数组中不能直接存储java对象。

6、数组一旦创建,在Java中规定,长度不可变。(数组长度不可变)

7、数组的分类:一维数组、二维数组、多维数组...(一维数组较多,二维数组偶尔使用!)

8、所有的数组对象都有length属性(java自带的),用来获取数组中元素的个数。

9、java中的数组要求数组中的元素的类型统一。比如int类型数组只能存储int类型,Person类型数组只能存储Person类型。

10、数组在内存方面存储的时候,数组中的元素内存地址(存储的每一个元素都是有规则的挨着排序的)是连续的。内存地址连续。这是数组存储元素的特点(特色)。数组实际上是一种简单的数据结构。

11、所有的数组都是拿“第一个小方框的内存地址”作为整个数组对象的内存地址。
       (数组中首元素的内存地址作为整个数组对象的内存地址。)

12、数组中每一个元素都是有下标的,下标从0开始,以1递增。最后一个元素的下标是:length - 1下标非常重要,因为我们对应数组中元素进行“存取”的时候,都需要通过下标进行。

13、数组这种数据结构的优点和缺点是什么?
     优点:查询/查找/检索某个下标的元素时效率极高,可以说查询效率最高的一个数组结构。
           为什么检索效率高?
               第一:每一个元素的内存地址在空间存储上是连续的。
               第二:每一个元素类型相同,所以占用空间大小一样。
               第三:知道第一个元素内存地址,知道每一个元素占用空间的大小,又知道下标,所以通过一个数学表达式可以计算出某个下标上元素的内存地址,直接通过内存地址定位元素,所以数组的检索效率是最高的。

               数组中存储100个元素,或者存储100万个元素,在元素查询/检索方面,效率是相同的,
               因为数组中元素查询的时候不会一个一个找,是通过数学表达式计算出来的。(算出一个
               内存地址,直接定位点的。)

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

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

    注意:
        对于数组中最后一个元素的增删,是没有效率影响的。

一维数组

1、怎么声明/定义一个一维数组?
        语法格式:

int[] array1;
String[] array2;

2、怎么初始化一个一个一维数组呢?
        包括两种方法:
                * 静态初始化一维数组

                        语法格式:

int[] array = {100, 200, 300, 500};

                * 动态初始化一维数组
                        语法格式:

int[] array = new int[5];  

这里的"5"表示数组的元素个数。初始化一个5个长度的int类型数据,每一个元素int类型默认值0

什么时候采用静态初始化方式,什么时候使用动态初始化方式呢?
        - 确定数组中存储哪些具体的元素时,采用静态初始化方式。
        - 不确定将来数组中存储哪些数据,可以采用动态初始化方式,预先分配内存空间。

下面这种风格也可以,但是这是C++风格,不建议java中使用。

int array[] = {1, 100, 10, 20, 55, 234};

输出数组中的个数

System.out.println("数组中元素的个数是:" + array.length);

数组中每一个元素都有下标,通过下标对数组中的元素进行读和改。

System.out.println("第一个元素 = " + array[0]); //1  读
array[0] = 111; // 改
System.out.println("第一个元素 = " + array[0]); //111

读取数组最后一个元素

System.out.println("最后一个元素 = " + array[5]);
System.out.println("最后一个元素 = " + array[array.length - 1]);

【注意】当操作的下标超过数组最大下标的时候,会报ArrayIndexOutOfBoundsException异常,数组下标越界异常,一定要注意下标别越界

System.out.println(array[6]);  // 抛出异常

遍历数组

for (int i = 0; i < array.length; i++) {
    System.out.println(array[i]);  // i是从0 到5,是下标
}

数组还可以存一些引用类型,还可以用到多态的知识。

3、关于一维数组的扩容:
        数组长度一旦确定不可变,那么数组满了,就需要扩容。
        java中对数组的扩容时:
                先新建一个大容量的数组,然后将小容量的数组中的数据一个一个的拷贝到大数组当中。
结论:
        数组扩容效率较低。因为涉及到拷贝的问题,所以在以后开发中请注意:尽可能少的进行数组的拷贝。可以在创建数组对象的时候预估一些多长合适,最好预估准确,这样可以减少数组的扩容次数,提高效率。

调用System类中的arraycocy方法,来完成数组的拷贝

String[] stcs = {"hello", "word", "java", "oracle"};
String[] newStcs = new String[20];
System.arraycopy(stcs, 0, newStcs, 0, stcs.length);
for (int i = 0; i < newStcs.length; i++) {
    System.out.println(newStcs[i]);
}

解读arraycocy方法(参数按顺序)

        stcs是拷贝源(从这个数组中拷贝)

        0 源数组中的起始位置

        newStcs 目标数组。

        0 目标数组中的起始位置。

        stcs.length 要复制的数组元素的数量

基本数据类型也是类似。

二维数组

1、二维数组其实是一个特殊的一维数组,特殊在这个一维数组当中的每一个元素是一个一维数组。
2、三维数组是什么?
        三维数组是一个特殊的二维数组,特殊在这个二维数组中每一个元素是一个一维数组。
        实际开发中使用最多的就是一维数组,二维数组也很少使用,三维数组几乎不用。
3、二维数组静态初始化

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

int[][] a = {
        {100, 200, 300},
        {30, 20, 40, 50, 60},
        {6, 7, 9, 1},
        {0},
};
System.out.println(a.length);  // 4
System.out.println(a[0].length);  // 3
System.out.println(a[1].length);  // 5
System.out.println(a[2].length);  // 4
System.out.println(a[3].length);  // 1

二维数组动态初始化(3个一维数组,每一个一维数组当中4个元素。)

int[][] ints = new int[3][4];

int[][] ints = new int[3][4];
System.out.println(ints.length); //3
System.out.println(ints[0].length); //4
System.out.println(ints[1].length); //4

关于二维数组中的元素的:读和写【注意别越界。】
        a[二维数组中的一维数组的下标][一维数组的下标]
        a[0][0] :表示第1个一维数组中的第1个元素。
        a[3][10] : 表示第4个一维数组中的第11个元素。
【注意】:
        对于a[3][10]来说,其中a[3]是一个整体,[10]是前面a[3]执行结束的结果然后再下标10.

System.out.println("第3个一维数组中第1个元素:" + a[2][0]); // 6
a[2][0] = 1000;
System.out.println(a[2][0]); //1000

遍历二维数组

for (int i = 0; i < a.length; i++) {  // 外层循环3次。(负责纵向)
    for(int j = 0; j < a[i].length; j++){
        System.out.print(a[i][j] + " ");
    }
System.out.println();
}

数组的排序及查找

冒泡排序

冒泡排序算法(以从小到大排序为例):
1、每一次循环结束之后,都要找到最大的数据,放到参与比较的这对数据的最右边。(冒出最大的那个气泡。)
2、核心:
        拿着左边的数字和右边的数字对比,当左边 > 右边的时候,交换位置。

public class BubbleSort {
    public static void main(String[] args) {
        // 这是int类型的数组对象
        int[] arr = {9, 8, 10, 7, 6, 0, 11};
        int count1 = 0;   // 计算循环比较次数
        int count2 = 0;   // 计算交换数据次数
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                count1++;
                if (arr[j] > arr[j+1]){
                    int t;
                    t = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = t;
                    count2++;
                }
            }
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
        System.out.println("该数组冒泡排序循环比较次数为:" +count1); //21
        System.out.println("该数组冒泡排序交换数据次数为:" + count2); //13
    }
}

选择排序

选择排序算法(以从小到大排序为例):

1、每一次从这堆“参与比较的数据当中”找出最小值,拿着这个最小值和“参与比价的这堆最前的元素”交换位置。
2、选择排序比冒泡排序好在:每一次的交换位置都是有意义的。
3、关键点:选择排序中的关键在于,你怎么找出一堆数据中最小的。

public class SelectSort {
    public static void main(String[] args) {
        int[] arr = {9, 8, 10, 7, 6, 0, 11};
        int count1 = 0;   // 计算循环比较次数
        int count2 = 0;   // 计算交换数据次数
        for (int i = 0; i < arr.length - 1; i++) {
            int min = i;
            for (int j = i+1; j < arr.length; j++) {
                count1++;
                if (arr[min] > arr[j]){
                    min = j;   // 最小值的元素小标是j
                }
            }
            if (min != i){
                int temp;
                temp = arr[min];
                arr[min] = arr[i];
                arr[i] = temp;
                count2++;
            }
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
        System.out.println("=================================");
        System.out.println("该数组选择排序循环比较次数为:" +count1); //21
        System.out.println("该数组选择排序交换数据次数为:" + count2); //5
    }
}

两个排序对比:冒泡排序和选择排序实际上比较的次数没变。交换位置的次数减少了。

数组元素一个一个查找

一个一个挨着找,直到找到为止。

创建一个数组工具类ArrayUtil,添加静态方法arraySearch

public class ArrayUtil {
    private static int arraySearch(int[] arr, int ele) {
        for (int i = 0; i < arr.length; i++) {
            if (ele == arr[i]){
                return i;
            }
        }
        return -1;
    }
}

解析:从数组中检索某个元素的下标(返回的是第一个元素的下标。)

        arr 被检索的数组 ,ele 被检索的元素

main中测试

int[] arr = {5, 6, 7, 89, 0};
int index = ArrayUtil.arraySearch(arr, 89);
System.out.println(index == -1 ? "该元素不存在!" : "该元素的下标为:" + index);

二分法查找

1、二分法查找(算法),这个效率较高。

2、二分法查找算法是基于排序的基础之上。(没有排序的数据是无法查找的。)

在数组工具类ArrayUtil,添加静态方法binarySearch

public class ArrayUtil {
    private static int binarySearch(int[] arr, int dest) {
        int begin = 0; // 开始下标
        int end = arr.length - 1; // 结束下标
        // 开始元素的下标只要在结束元素下标的左边,就有机会继续循环。
        while (begin <= end){
            int mid = (begin + end) / 2; // 中间元素下标
            if (arr[mid] == dest){
                return mid;
            }else if (arr[mid] < dest){
                begin = mid + 1;  // 一直增
            }else {
                end = mid - 1;   // 一直减
            }
        }
        return -1;
    }
}

解析:从数组中查找目标元素的下标
      arr 被查找的数组(这个必须是已经排序的),dest 目标元素

        返回值-1表示元素不存在,其它表示返回该元素的下标。

测试

int[] arr = {100, 200, 230, 260, 300, 350, 400};
int index = binarySearch(arr, 200);
System.out.println(index == -1 ? "该元素不存在!" : "该元素下标是:" + index);

数组工具类

SUN公司已经为我们写好了一个数组工具类:java.util.Arrays; 开发的时候要参考API帮助文档。

int[] arr = {3, 6, 5, 34, 1, 3, 5, 32};
Arrays.sort(arr); // 排序
// 遍历
for (int i = 0; i < arr.length; i++) {
    System.out.println(arr[i]);
}
// 二分法查找(建立在排序基础之上。)
int index = Arrays.binarySearch(arr, 5);
System.out.println(index == -1 ? "该元素不存在!" : "该元素下标是:" + index);

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/315152.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号