这是一篇网上搜到的文章,对数组进行了充分的说明。楼主懂了数组的俩种初始化方式:静态初始化和动态初始化方式。(贴过来备用哦)



下面我带大家一起加深一下对Java数组的认识:

1.理解数组

数组也是一种数据类型,本身就是一种引用类型,我们从它的初始化方法,通过关键字new去完成定义及初始化就可以知道。

数组的长度是不变的,一旦数组完成初始化后,它的长度就固定下来了,在内存中占有的空间也就固定了,即使里面的数据被清空了,占有的空间还是保留下来了,依然是属于数组的,当然长度依旧是不变的。

数组里边存放的数据类型要一致,可以基本数据类型,也可以是引用数据类型,但是唯一的标准就是相同的类型。在Java中,类与类是支持继承关系的,所以就可能造成数组里面可以存在多中数据类型的假象:

示例:

class Animal {

    public String name;

    public Animal(String name) {
this.name = name;
}
} class Cat extends Animal { public Cat(String name) {
super(name);
}
} class Dog extends Animal { public Dog(String name) {
super(name);
}
} public class ArrayDemo { public static void main(String[] args) { Animal[] animals = new Animal[2];
Cat cat = new Cat("little cat");
Dog dog = new Dog("little dog");
animals[0] = cat;
animals[1] = dog;
System.out.println(animals[0].name);
System.out.println(animals[1].name);
}
}

这样看上去,好像数组里面存放了Cat类型和Dog类型,但是实际上他们都是Animal类型,数组里面都是相同的类型,请大家不要搞混淆了,哈哈。

2.定义数组和初始化数组

定义数组的语法格式:

type[] arrayName;
type arrayName[];

这两种格式,我是强烈推荐第一种的,第一种格式给人非常的明确,定义了一个变量,它是type数组类型,但是第二种就可能给人一种假象,定义了一种变量,它是type类型的,为了不给别人误会,还是选择第一种好点咯。

定义完了数组,这是内存中还没给数组分配空间,真正分配内存空间的时候就是在给数组初始化的时候。

初始化数组分两种:

静态初始化:

arrayName = new type[]{element1,element2, element3......};

由上面很容易看出静态的初始化就是显式指定数组每个元素的初始值,由系统决定数组的长度。

动态初始化:

arrayName = new type[length];

由上面看出动态初始化就是只指定数组的长度,由系统为数组分配初始值。

对于不同类型,系统分配的初始值也是不一样的。

类型

初始值

整数类型(byte、short、int、long)

0

浮点类型(float、double)

0.0

字符类型(char)

'\u0000'(代表空格)

布尔类型(boolean)

false

引用类型(类、接口、数组)

null

你可能产生这样的猜想:不是可以同时使用静态初始化和动态初始化吗?

答案是不可以的,编译器是提示Cannot define dimension expressions when an array initializer is provided,因为你定义了长度,说明你已经初始化完了,我想想也是觉得这样不合理的,如果可以两者混合使用的话,那么我定义好了数组的长度后,系统是不是要给它附上默认的初始值,但是你后面又是静态的初始化,指定了特定的值,系统又要为你改变里面的值,这样做系统真累,我也觉得累。当然编译器是不支持两者混合使用的,大家注意了!

3.数组的使用

数组的使用就是引用数组的索引,数组的索引是从0开始的,到length-1为止,如果超过了这样范围就是抛出java.lang.ArrayIndexOutOfBoundException异常,就是数组索引越界异常,引用数组的使用太简单了,下面就简单用for和foreach来演示一下访问:

public class ArrayDemo2 {

    public static void main(String[] args) {

        String[] strings = new String[]{"hello", "world"};

        for(int i = 0; i < strings.length; i++)
System.out.println(strings[i]); for(String string : strings)
System.out.println(string);
}
}

4.内存中的数组:

type[] arrayName = new type[]{element1, element2, element3......};

arrayName就是一个引用的变量,这个数组的引用变量可以指向任何有效的内存,只有当指向有效的内存后才可以方位数组元素,可以这么说,引用变量是访问真是对象的根本方式。

实际的数组对象被存储在堆(heap)内存中,如果引用该数组独享的数组引用变量是一个局部变量的话,那么它被存储在栈(stack)内存中,示意图如下:

由这里我们可以很清楚的看出局部数组引用变量是怎么访问到内存中的数组的,党当一个方法调用完后,局部变量就没了,也就是从栈内存中消失了,如果堆内存中数组不再有任何引用变量指向自己,这个数组将成为垃圾,该数组所占的内存就会被系统的垃圾回收机制回收,因此,为了让垃圾回收机制回收一个数组所占的内存空间,可以将数组变量赋值为null,也就切断了数组引用变量和实际数组之间的关系,实际的数组也就成为了垃圾。

在这里,我们让一个引用变量指向另外一个实际的数组的时候,可能产生数组长度可变的假象,大家来看看一个例子:

public class ArrayDemo3 {

    public static void main(String[] args) {

        int[] a = new int[]{1, 2};
int[] b = new int[4];
System.out.println("length of b:" + b.length); b = a;
System.out.println("length of b:" + b.length);
}
}

结果:

length of b:4
length of b:2

从上面看我们b数组的长度好像发生了变化,但是实际上不是这样的,我们来分析一下内存中的变化:

先是这样:

然后这样:

我们所说的数组的长度不变是针对堆内存中真正数组的长度,引用变量是可以改变指向的,指到哪里肯定就显示指到的数组的长度了,但是真正的长度是不曾改变的。

5.操作数组的工具类:

Java提供的Arrays类里包含的一些static修饰的方法可以直接操作数组

int binarySearch(type[] a, type key):使用二分法查询key元素值在a数组中出现的索引,如果a数组不包含key元素值,就返回负数,调用该方法的前提是数组中的元素已经按照升序排列好了。

type[] copyOf(type[] original, int newLength):这个方法可以将original数组复制到一个新的数组,这个新的数组的长度为newLength。

boolean equals(type[] a, type[] b):如果a数组和b数组的长度相等,而且数组中的元素一一相等,该方法就返回true。

void fill(type[] a, type val):该方法会将数组中的全部元素赋值为val。

void sort(type[] a):该方法对a数组进行(升序)排序。

Java数组!!!你知多少?的更多相关文章

  1. Java数组你知多少?

    下面我带大家一起加深一下对Java数组的认识: 1.理解数组 数组也是一种数据类型,本身就是一种引用类型,我们从它的初始化方法,通过关键字new去完成定义及初始化就可以知道. 数组的长度是不变的,一旦 ...

  2. java数组学习

    1. java数组的静态特性:          java是静态语言,java中数组的长度是固定的.还有,数组元素的类型也是在定义时指定了的. 2. java数组里的关键词:          数组变 ...

  3. 第5节:Java基础 - 必知必会(下)

    第5节:Java基础 - 必知必会(下) 本小节是Java基础篇章的第三小节,主要讲述Java中的Exception与Error,JIT编译器以及值传递与引用传递的知识点. 一.Java中的Excep ...

  4. Java面试必知必会(扩展)——Java基础

    float f=3.4;是否正确? 不正确 3.4是双精度,将双精度赋值给浮点型属于向下转型,会造成精度损失: 因此需要强制类型转换: 方式一:float f=(float)3.4 方式二:float ...

  5. Java面试必知必会:基础

    面试考察的知识点多而杂,要完全掌握需要花费大量的时间和精力.但是面试中经常被问到的知识点却没有多少,你完全可以用 20% 的时间去掌握 80% 常问的知识点. 一.基础 包括: 杂七杂八 面向对象 数 ...

  6. Java 数组

    数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同. Java语言中提供的数组是用来存储固定大小的同类型元素. 你可以声明一个数组变量,如numbers[100 ...

  7. 第5章 Java数组

    1.什么是数组 数组可以想象成一个巨大的盒子,这个盒子里面存放的是同一个数据类型的数据 例如:int[] scores = {78,68,94,93}; 2.如何使用Java中的数组 2.1申明数组 ...

  8. Java 数组基础

    数组 数组(Array):相同类型数据的集合. 定义数组 方式1(推荐,更能表明数组类型) type[] 变量名 = new type[数组中元素的个数]; 比如: int[] a = new int ...

  9. Java数组及其内存分配

    几乎所有的程序设计语言都支持数组.Java也不例外.当我们需要多个类型相同的变量的时候,就考虑定义一个数组.在Java中,数组变量是引用类型的变量,同时因为Java是典型的静态语言,因此它的数组也是静 ...

随机推荐

  1. 《啊哈算法》中P81解救小哈

    题目描述 首先我们用一个二维数组来存储这个迷宫,刚开始的时候,小哼处于迷宫的入口处(1,1),小哈在(p,q).其实这道题的的本质就在于找从(1,1)到(p,q)的最短路径. 此时摆在小哼面前的路有两 ...

  2. Vector 和 Array 区别

    1:array 定义的时候必须定义数组的元素个数;而vector 不需要:且只能包含整型字面值常量,枚举常量或者用常量表达式初始化的整型const对象, 非const变量以及需要到运行阶段才知道其值的 ...

  3. 举枪消灭"烂代码"的实战案例

    前言 之前我写过一篇如何少写PHP "烂"代码 https://segmentfault.com/a/11...感觉很多新人对此不太理解.今天以打卡功能为例,去讲解其中的奥秘.那篇 ...

  4. fork()调用使子进程先于父进程被调度

    由于内核使用写时复制机制,fork之后父子进程是共享页表描述符的,如果让父进程先执行,那么有很大几率父进程会修改共享页表指向的数据,那么内核此时必须给父进程分配并复制新的页表供父进程修改使用,那么如果 ...

  5. [转]如何有效地报告Bug

    英文原文:Simon Tatham,编译:Dasn 引言 为公众写过软件的人,大概都收到过很拙劣的bug报告,例如: 在报告中说“不好用”: 所报告内容毫无意义: 在报告中用户没有提供足够的信息: 在 ...

  6. qwb和李主席

    qwb和李主席 Time Limit: 4 Sec  Memory Limit: 128 MB Description qwb和李主席打算平分一堆宝藏,他们想确保分配公平,可惜他们都太懒了,你能帮助他 ...

  7. noip模拟赛 排序

    分析:因为序列是不严格单调的,所以挪动一个数其实就相当于把这个数给删了.如果a[i] < a[i-1],那么可以删掉a[i],也可以删掉a[i-1](!如果没考虑到这一点就只有90分),删后判断 ...

  8. sql server使用杂记

    SqlServer导出数据库 navcat for sql server中打开连接,打开数据库,右键--数据传输,常规选项卡--模式选择dbo,目标选择连接(选择你新建的库)或者文件(导出你要的sql ...

  9. RDS for MySQL Online DDL 使用

    https://help.aliyun.com/knowledge_detail/41733.html?spm=5176.7841698.2.17.u67H3h

  10. Clojure:将两个list合并成一个map

    假设我们有两个list,分别是: (def a [“one” “two” “three”]) (def b [1 2 3]) 我们要把它们合为一个键值对应的map,做法很简单: 1. 先将a和b合为一 ...