Java数组

1.了解数组

数组,大家都不陌生,数组对于每一门编程语言都是重要的数据结构之一,当然不同编程语言对于数组的应用和实现也稍有不同。
那么让我们了解一下Java语言提供的数组。

1.1.什么是数组?

概念:数组是具有相同数据类型且按一定次序排列的的一组变量的集合体。即:
1.存储多个数据。
2数组中的每个元素具有相同数据类型。
3从内存结构的角度理解:数组在内存中是一段连续的内存空间,即在内存中连续存储。
4.数据类型可以是任何数据类型,包括基本类型和引用类型。
简而言之,定义一个数组就是一次定义多个变量。

1.2.什么是数组元素?

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

1.3.什么是数组长度?

数组中元素的个数叫做数组长度,也叫作数组大小。
获取数组长度的方法:数组名.length
数组大小是在为数组元素分配内存时确定的大小,大小不可改变。

1.4.什么是数组下标?

下标是数组元素在数组中的位置。下表也叫索引( index)。
在一个数组中,数组下标是用整数表示的,从0开始,依次累加1,直到数组长度-1。即:
下标的界限 0 到 数组长度-1。
下标如果为负数,或者下标超过了数组大小-1,此时会发生数组下标越界。(ArrayIndexOutOfbounds)

1.5.数组的数据结构(线性表):

线性表,全名为线性存储结构。使用线性表存储数据的方式可以这样理解,即“把所有数据用一根线儿串起来,再存储到物理空间中”。
如下图就是线性表的存储结构:


线性表

2.使用数组

根据数组的维度,可以将其分为一维数组、二维数组和多维数组等

2.1.使用数组的步骤:

1.定义数组(数组的声明)
2.为数组元素分配内存
3.数组元素初始化
4.使用数组

2.1.1.定义数组(声明数组):

定义数组的两种语法规则:
1.数据类型 [ ] 数组名; (推荐)
2.数据类型 数组名[ ] ;

例如:
int []score; 
int score[];  

1.数组是什么数据类型,数组是元素就是什么数据类型。
2.数组的特征是[ ]([ ]表示数组)
3.数组是引用类型。

定义数组的本质就是向JVM申请内存,JVM将内存划分成几个区域,其中包括堆和栈,不同的区域储存不同类型的数据。
定义数组时,JVM将数组的名称存储在栈中,栈是一种先进后出的数据结构,因此数组名称在栈中。数组是引用类型,因此数组名称的默认值是null。

2.1.2.为数组元素分配内存:

声明一个数组时仅为数组指定了数组名称和元素的类型,并未指定元素的个数,没有为数组元素分配内存。因为没有为数组元素分配内存,此时无法使用数组存储数据。要让系统为数组元素分配内存,必须要指明数组元素的个数,并通过new运算符为数组元素分配内存。
为数组元素分配内存的语法格式:
数组名=new 数据类型[数组长度]
例如:score=new int[4];
定义数组和为数组元素分配内存,这两步可以合并一起写,例:

int [ ]score=new int[4];

(因为数据类型为int类型,此时还未为数组元素初始化,所以数组元素的默认值是0。)
内存分配如下图所示:


数组元素内存分配

2.1.3.数组元素初始化:

数组声明并为数组元素分配内存空间完成后,必须为数组元素初始化(初始化就是第一次赋值的意思)后,才能使用数组元素。如果没有为数组元素初始化,那么数组元素为默认值。各种数据类型数组元素的默认值见表:

数组元素基本类型 默认初始值
byte,int,short ,long 0
float,double 0.0
char '\u0000'
boolean false
引用数据类型 null

可以通过数组下标对数组元素初始化,例如:

array[0]=65;        //表示数组的第一个数组元素赋值为65

数组的几种初始化方式:

1.静态初始化(静态初始化时, {}中数据类型必须与[]前数据类型一致。)

数据类型 [ ] 数组名称 = new 数据类型[ ]{数组元素1,数组元素2,数组元素3…};
或者 ,
数据类型 [ ] 数组名称 = {数组元素1,数组元素2,数组元素3…};

2.动态初始化

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

定义数组、为数组元素分配内存、数组元素初始化,可以放在一步写,例如:

int [ ]score=new int[4]; 
int [ ]score=new int[]{84,45,96,78};
int [ ]score={84,45,96,78}

2.1.4使用数组:

使用数组通常都是求数组中的最大值、最小值、总和、平均值、遍历数组元素、数组元素排序、数组元素中元素的数量等操作。
我们可以通过实例来理解如何使用数组:

2.1.4.1.最大值,最小值,平均值,求和:

例:班级5个学生,创建一个成绩的数据,统计最大值,最小值,平均值,求和:
public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    //定义数组、为数组元素分配内存
    int[] scores = new int[5];
    //数组元素初始化
    for (int i = 0; i < scores.length; i++) {    //遍历数组
        System.out.printf("请输入第%d位同学的成绩:", (i + 1));
        scores[i] = scanner.nextInt();
    }
    //使用数组
    int max = scores[0];
    int min = scores[0];
    for (int i = 1; i < scores.length; i++) {
        if (max < scores[i]) {         //求最大值
            max = scores[i];
        }
        if (min > scores[i]) {        //求最小值
            min = scores[i];
        }
    }
    System.out.println("成绩最大值为:" + max);
    System.out.println("成绩最小值为:" + min);
    //求和
    int sum = 0;
    for (int i = 0; i < scores.length; i++) {
        sum += scores[i];
    }
    System.out.println("总分为:" + sum);
    //平均值
    System.out.println("平均分为:" + sum / scores.length);
}

2.1.4.2.用增强for循环遍历数组:

jdk1.5版本及其之后的版本提供了增强for循环语句,用来对数组和集合中的数据进行遍历,增强for循环的语法规则:
for(元素类型 变量名:要循环的数组或集合){
.......
}

1.元素类型是指数组或集合中的元素的类型。
2.变量名在循环时用来保存每个元素的值。
3.冒号后面是要遍历的数组或集合的名称。例如:

 public static void main(String[] args) {
        int []arrays={45,79,54,87};
        for (int a:arrays) {
            System.out.print(a);   //遍历arrays数组
        }
    }

2.1.4.3.数组元素排序:

常用的排序算法:冒泡排序、选择排序、插入排序、快速排序、希尔排序、归并排序、快速排序、基数排序、堆排序、计数排序、桶排序、二叉树排序。前四种是比较常用的算法,而冒泡排序是最重要的一种排序算法。

冒泡排序:
冒泡排序
    public static void main(String[] args) {
        //冒泡排序
        int []score = {45,74,68,58,89};
        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;
                }
            }
        }
        System.out.println(Arrays.toString(score));
    }
选择排序:
选择排序
public static void main(String[] args) {
        //选择排序
        int[] arr ={45,74,68,58,89};
        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;
        }
        System.out.println(Arrays.toString(arr));
    }
插入排序:
插入排序
public static void main(String[] args) {
        //插入排序
        int[] arr ={45,74,68,58,89};
        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;
                    j--;
                }else {
                    break;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }
快速排序:
快速排序
public static void main(String[] args){
    //快速排序
    int[] arr ={45,74,68,58,89};
    quickSort(arr,0,arr.length-1);
    System.out.println(Arrays.toString(arr));
}
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);
}

2.1.4.4.查找数组元素:

二分查找:
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;
}

3.数组的工具类java.util.Arrays类

3.1.比较两个数组是否相等:equals(array1,array2);

    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的长度及元素是否相等
    }

3.2.对数组元素进行升序排序:sort(arr);

数组全部排序:
    public static void main(String[] args){
        int []arr1 = {10,50,40,30};
        Arrays.sort(arr1);
        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,3,arr1.length-1);
        for (int i = 0; i < arr1.length; i++) {
            System.out.println(arr1[i]);
        }
    }

3.3.将数组转换成字符串:toString(arr);

    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));
    }

3.4.将数组所有元素赋值为相同的值:fill(arr,key);

    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));
    }

运行结果:
[30, 30, 30, 30, 30, 30, 30, 30]

3.5.将数组赋值成一个长度为设定值的新数组:copyOf(arr1,arr2.length)

    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));
        //将arr1复制成长度为30的新数组arr3
        int []arr3 = Arrays.copyOf(arr1,30);
        System.out.println(Arrays.toString(arr3));
    }

运行结果:
[10, 50, 40]
[10, 50, 40, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

3.6.查询元素在数组中的下标:binarySearch(arr[],index);

    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);
    }

运行结果
0
-1
-4
-5

分析:

  1. 若找到了数据,则返回该数据的下标;若找不到数据,则返回负数,其值为该数据在数组中排序的位置

4.二维数组

在实际运用中,三维及其以上的数组使用的很少,主要使用二维数组。
使用二维数组的步骤与使用一维数组的步骤相同:1.定义数组(数组的声明)、2.为数组元素分配内存、3.数组元素初始化、4.使用数组

4.1.定义二维数组(数组的声明):

定义二维数组的两种语法规则:
1.数据类型 [ ] [ ]数组名;
2.数据类型 数组名[ ] [ ];

4.2.为二维数组元素分配内存:

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

int [ ] [ ]s=new int[3] [3];
内存分配

4.3.二维数组元素初始化:

示例:

int arr[ ] [ ]=new int[ ] [ ]{{1,2,3},

                              {4,5,6},

                              {7,8,9},

};

int arr[ ] [ ]={{1,2,3},

                {4,5,6},

                {7,8,9},

};

4.4.使用二维数组:

让我们看一个小例子便于理解:

public static void main(String[] args) {
    //创建定义二维数组
    int[][] scores = new int[3][4];
    //创建Scanner
    Scanner input = new Scanner(System.in);
    //给每个二维数组中的一维数组赋值
    for(int i = 0; i < scores.length; i++){
        for(int j = 0; j < scores[i].length; j++){
            System.out.println("输入整数");
            scores[i][j] = input.nextInt();
        }
    }
    //查看二维数组中的一维元素
    for (int i = 0; i < scores.length; i++) {
        System.out.println(Arrays.toString(scores[i]));
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • 什么是数组 所谓数组,是具有相同数据类型的若干变量或者数据按照一定排序规则组合起来的一种数据存储格式。数组中的数据...
    老夫不正经阅读 393评论 0 1
  • 1.了解数组 数组,大家都不陌生,数组对于每一门编程语言都是重要的数据结构之一,当然不同编程语言对于数组的应用和实...
    凝时阅读 1,143评论 2 22
  • 数组: 数组是具有多个连续存储的相同数据类型的变量组成的集合体。 数组元素: 构成一个数组的每一个数据都是数组元素...
    咸鱼王_d5fd阅读 1,081评论 1 22
  • Java数组 数组就是用来存储一批同种类型数据的内存区域(可以理解为容器) 数组的定义 静态初始化数组 定义数组的...
    每天起床都想摆阅读 408评论 0 2
  • 数组的概念: 数组是一个容器,存放一组相同数据类型变量的容器 数组的格式: 数据类型[] 数组名; Java写法 ...
    i_4178阅读 455评论 0 0