【骚全带你学Java---九、认识java数组】

duwenquan-方形LOGO.png

java中数组

数组是指一组数据的集合,数组中的每个数据称为元素。在Java中,数组也是Java对象。数组中的元素可以是任意类型(包括基本类型和引用类型),但同一个数组里只能存放类型相同的元素。

数组的定义与初始化

定义及动态初始化
  • 方式一,java推荐用法: type [] 变量名 = new type[数组中元素的个数];
 //举例
  int[] a = new int[10];
   for (int i = 0; i < a.length; i++){
       a[i] = new Random().nextInt();
   }
  • 方式二,c语言用法(不推荐): type 变量名 [] = new type[数组中元素的个数];
  int a[] = new int[10];
    for (int i = 0; i < a.length; i++){
        a[i] = new Random().nextInt();
    }
静态初始化
int[] a=new int[]{1,2,3};

在定义数组的时候直接初始化,大括号里的值就是数组的值。

隐式初始化
int[] a={1,2,3};

可以不写new,直接使用大括号初始化,但是本质上还是调用了new的,只是可以不写出来而已,所以叫隐式初始化。

最后,我们回过头来仔细的研究一下下面这一句代码,这句代码又做了什么事情?

int[] a = new int[10];
//这句代码做了哪些事呢?

int[] a: 定义了一个int型数组的引用,名字叫做a,存放在栈中。
new int[10]:初始化一个长度为10的int型数组,在堆中开辟相应大小的内存。
int[] a = new int[10]:将堆中开辟的数组的内存地址赋给数组引用a。

数组的使用

数组的引用

可以通过下标来引用数组:arrayName[index];与C、C++不同,Java对数组元素要进行越界检查以保证安全性。这个iOS是一样的。

int[] a=new int[]{2,5,7,4};
System.out.println(a[2]);
//运行结果为  7,[注]数组的下标都是从0开始的,这也是每一种开发语言的共性
数组的长度

java中的每个数组都有一个名为length的属性,表示数组的长度。

int[] a=new int[]{2,5,7,4};
int length = a.length;
System.out.println(length);
//输出结果为:4
数组的遍历
  • 方式一:for循环【此方法适应大部分开发语言】
int[] a= new int[]{1,3,5,7,9};
for(int i=0;i<a.length;i++){
 System.out.println(a[i] + " ,");
}
//运行结果为: 1 ,3 ,5, 7, 9,
  • 方式二:foreach循环
int[] a= new int[]{1,3,5,7,9};
foreach(int element: a){
 System.out.println(element);
}
//运行结果为:1 3 5 7 9
数组元素不为基本数据类型

数组是可以存放任意类型的数据的,不一定非得是基本数据类型。数组元素不为基本原生数据类型时,存放的是引用类型,而不是对象本身。当生成对象之后,引用才指向对象,否则引用为null。

   Person[] p = new Person[3];

       //未生成对象时,引用类型均为空
       System.out.println(p[0]);


       //生成对象之后,引用指向对象
       p[0] = new Person(10);
       p[1] = new Person(20);
       p[2] = new Person(30);

       for(int i = 0; i < p.length; i++){
           System.out.println(p[i].age);
       }
数组作为方法的参数
public void printArray(int[] array) {
  for (int i = 0; i < array.length; i++) {
    System.out.print(array[i] + " ");
  }
}
数组作为方法的返回值
public int[] reverse(int[] list) {
  int[] result = new int[list.length];

  for (int i = 0, j = result.length - 1; i < list.length; i++, j--) {
    result[j] = list[i];
  }
  return result;
}
数组内容的输出

错误示例展示

public static void main(String[] args) {
    int a[]={1,9};
    System.out.println(a.toString());
}
//[I@61bbe9ba

这输出的是什么奇怪的东西?我们先不管,后面会详细说。那怎么输出数组呢?

  • 方式一
public static void main(String [] args){
        int a[]={1,9};
        for (int i : a){
            System.out.println(i);
        }
    }
  • 方式二
 public static void main(String [] args){
        int a[]={1,9};
        System.out.println(Arrays.toString(a));
    }
数组内容的比较

数组内容的比较可以使用equals()方法吗? 看代码:

public class ArrayTest{
      public static void main(String[] args){
             int[] a = {1, 2, 3};
             int[] b = {1, 2, 3};

             System.out.println(a.equals(b));
             //结果是false。
      }    
}

所以证明不能直接用equals()方法比较数组内容,因为没有override Object中的实现,所以仍采用其实现,即采用==实现equals()方法,比较是否为同一个对象。

怎么比较呢?一种解决方案是自己写代码,另一种方法是利用java.util.Arrays。

java.util.Arrays中的方法全是static的。其中包括了equals()方法的各种重载版本。

代码如下:

import java.util.Arrays;
public class ArrayEqualsTest{

    public static boolean isEquals(int[] a, int[] b){
        if( a == null || b == null ){ 
            return false;
        }
        if(a.length != b.length){
            return false;
        }
        for(int i = 0; i < a.length; ++i ){
            if(a[i] != b[i]){
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args){
        int[] a = {1, 2, 3};
        int[] b = {1, 2, 3};

        System.out.println(isEquals(a,b));
        System.out.println(Arrays.equals(a,b));
    }
}
Arrays类的使用
  • 给数组赋值:通过 fill 方法。
  • 对数组排序:通过 sort 方法,按升序。
  • 比较数组:通过 equals 方法比较数组中元素值是否相等。
  • 查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作。
  • …….

数组的高级应用

二维数组

二维数组是数组的数组。其实java只有一维数组,但是由于数组可以存放任意类型的数据,当然也就可以存放数组了,这个时候,就可以模拟多维数组了。
基本的定义方式也是两种,代码示例如下:

  type[][] i = new type[2][3];//(推荐)

  type i[][] = new type[2][3];
变长的二维数组

二维数组的每个元素都是一个一维数组,这些数组不一定都是等长的。

声明二维数组的时候可以只指定第一维大小,空缺出第二维大小,之后再指定不同长度的数组。但是注意,第一维大小不能空缺(不能只指定列数不指定行数)。

public class ArrayTest4{
    public static void main(String[] args){
        //二维变长数组
        int[][] a = new int[3][];
        a[0] = new int[2];
        a[1] = new int[3];
        a[2] = new int[1];

        //Error: 不能空缺第一维大小
        //int[][] b = new int[][3];
    }
}

二维数组也可以在定义的时候初始化,使用花括号的嵌套完成,这时候不指定两个维数的大小,并且根据初始化值的个数不同,可以生成不同长度的数组元素。

int[][] c = new int[][]{{1, 2, 3},{4},{5, 6, 7, 8}};
可变参数

有的时候,你需要一个方法,但是你在调用它之前不知道要传递几个参数给他,这个时候你就需要可变参数了。

public static void main(String [] args){
    System.out.println(add(2,3));
    System.out.println(add(2,3,5));
}
public static int add(int x,int ...args){
    int sum=x;
    for(int i=0;i<args.length;i++){
        sum+=args[i];
    }
    return sum;
}

那个奇怪的int ...args就是可变参数,这样你就可以传递任意个你想传递的数据了。
java把可变参数当做数组处理。
[注意]:可变参数必须位于最后一项。当可变参数个数多余一个时,必将有一个不是最后一项,所以只支持有一个可变参数。因为参数个数不定,所以当其后边还有相同类型参数时,java无法区分传入的参数属于前一个可变参数还是后边的参数,所以只能让可变参数位于最后一项。

数组复制
nt[] a = new int[]{1,2};
int[] b = a;
b [1] = 5;

这个时候a[1]也变成了5,为什么会这样?就不用我多说了吧,所以,要拷贝一个数组,还是需要些技巧的:

  • 方式一:System.arraycopy的用法
int[] src = {1,3,5,7,9,11,13,15,17};

int[] dest = {2,4,6,8,10,12,14,16,18,20};

//从src中的第一个元素起复制三个元素,即1,3,5复盖到dest第2个元素开始的三个元素

System.arraycopy(src, 0, dest, 1, 3);

System.out.println(Arrays.toString(dest));

//[2, 1, 3, 5, 10, 12, 14, 16, 18, 20]
  • 其他方式:Array类的一些方法:如 Arrays.copyOf,Arrays.copyOfRange等。在下一篇会有专门的介绍。

数组的常见异常

1. NullPointerException 空指针异常

原因: 引用类型变量没有指向任何对象,而访问了对象的属性或者是调用了对象的方法。

2.ArrayIndexOutOfBoundsException 索引值越界。

原因:访问了不存在的索引值。

public static void main(String[] args) {

int[] x = { 1, 2, 3 };

System.out.println(x[3]);

//java.lang.ArrayIndexOutOfBoundsException

}

数组的好处

存数据和不存数据有什么区别吗?数组的最大好处就是能都给存储进来的元素自动进行编号. 注意编号是从0开始。方便操作这些数据。
例如 学生的编号,使用学号就可以找到对应的学生。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,587评论 18 399
  • 一转眼我都快三十了,都说三十而立,感觉自己似乎像一幅正在创作的水彩画,追求完美却始终不能长存。 我可以把我...
    杨玉申阅读 161评论 0 6
  • 第一次写手机测评文章,虽然已经用过很多数码产品,偶尔也想给它们写篇回忆录,在不同的时间段,有它们的陪伴,带给我不同...
    寒七寒阅读 386评论 0 0
  • 上一篇 早上起床的时候,胃部传来了强烈的呕吐感,我还没来得及离开我的床,就被这来势汹汹的呕吐给侵袭了。这是前几天急...
    两只黑喵阅读 324评论 0 0
  • 高玉竹阅读 106评论 0 0