java入门(5)--数组

数组是复合类型

数组是复合类型,内建的复合类型。它与字符串同属于"类--对象"范畴,有着与“基本类型”很不同的行为和特性。

首先的不同是,这些复合类型都有“方法”,可以通过““操作来调用。

比如:

String s = "abc";

int n = s..length();  //取得字符串的长度

基本类型如 int double char 等是不能进行点操作的。

另外,有些复合类型还有“属性”,其调用与方法类似,只是不加圆括号。

比如,求数组的长度就不是调用方法,而是属性。

int[] a = {1,2,3,4};

int n = a.length;

还有最最重要的一个不同,复合类型是有引用这个说法的。

当我们写:int a = 5; 的时候,a 变量里装的就是一个整数。

double b = 3.14;  则 b 中装的就是浮点数。b 占用的空间比 a 要大。

如果换成复合类型就不同了。

String a = "1234";

String b = "1234567";

这里的 a 和 b 都不是字符串本身,而是指向字符串对象的引用(类似于 c 语言中的指针),

引用的本质就是对象在内存中的地址。因而,不管对象有多大,引用的大小总是固定的,只占用很小的内存。

既然引用和对象是分离的实体,如果我们写:

String s;

这时,只建立了一个引用变量,还没有关联到某个对象。

如果我们需要明确地说:我的这个引用就是不指向任何对象,可以这样写:

String s = null;

关于类,对象,引用等面向对象的更多的理论,在以后的专题中讨论。

这里,只要先知道这种类型与基本类型有些不同,提高警惕也就是了。

创建数组的方法

可以直接通过给出数组的元素来创建数组对象,并初如化。

double[] a = {1.0, 1.5, 2.0, 2.5, 4.0, 4.3};

上面的代码先创建了一个引用 a,它的类型是:double[],即指向浮点数组的引用。

然后,创建了一个数组对象,该数组对象包含 6 个元素(即数组的长度为 6),元素的类型是 double

然后,用花括号中的数据为每一个元素进行初始化。

最后,把新创建的数组对象的地址写入到 a 中,即让 a 引用指向这个刚刚创建的数组对象。

也可以:

double[] a = new double[6];
a[0] = 1.0;
a[1] = 1.5;
a[2] = 2.0;
...

这段代码则是先创建了 包含 6 个元素的数组,但并不去分别对每个元素赋值。

接下来的代码再一个元素一个元素地赋值。

需要注意的是,不同于 c 语言,这里如果没有其下的赋值代码,元素中也是有固定值的,并不是一个随机数字。

java 中约定,变量总是会默认初始化,根据类型不同有不同的初始化值。

int double char 都是 0

boolean 是 false, 引用类型则是 null

 数组的基本操作

数组的基本操作是:求它的长度,读取每个元素的值,为某个元素赋值。

下面的代码求一个数组中所有元素的最大值。

 1 public class A0410
 2 {
 3     public static void main(String[] args){
 4         double[] a = {2.3, 4.5, 12.6, 0.4, 7.8, 9.2, 1.7};
 5         double m = a[0];
 6         for(int i=1; i<a.length; i++){
 7             if(a[i] > m) m = a[i];
 8         }
 9         System.out.println(m);
10     }
11 }

这是求多个数中最大值的基本手段,应该尽早熟悉,其思想类似于擂台赛。

请注意,java 与 c 语言一样,数组的下标都是从 0 开始的。所以最大的下标是: a.length-1

下面看这样一个问题:

假设你面前有 50 个空盒子,其编号是 1 ~ 50

现还,你在第 1 个盒子里放 1 颗豆子,在第 2 个盒子里放 2 颗豆子, 在第 3 个盒子里放 4 颗豆子 ....

总之,后面的盒子中的豆子数是前一个盒子的 2 倍。

那么,要完成这个任务,你一共需要多少颗豆子?

 1 public class A0410
 2 {
 3     public static void main(String[] args){
 4         long[] a = new long[50];
 5         // 放豆子
 6         a[0] = 1;
 7         for(int i=1; i<a.length; i++){
 8             a[i] = a[i-1] * 2;
 9         }
10         // 统计总数
11         long sum = 0;
12         for(int i=0; i<a.length; i++){
13             sum += a[i];
14         }
15         
16         System.out.println(sum);
17     }
18 }

这里需要注意,豆子的数目会很快地增长,用 int 类型存储是不够的。你可能会想,如果盒子更多怎么办?

不用急,java提供了 BigInteger 类型,可以表示任意大的整数。

为了逻辑上的清晰,我们把放豆子和求和这两个步骤分开了,实际上,可以边放豆子,边统计总数。

甚至是,根本不用数组,直接累加就可以!!

数组作为参数传递

数组可以像其它类型一样,在调用方法时,作为参数传递。

但需要高度警惕,数组是对象,而程序中写出的貌似数组的变量,实际上只是指向数组的指针而已。

我们在方法间传递的是引用,不是数组对象本身,这十分重要!!

因为这意味着:被调方与主调方共享同一个数组对象,一方修改,另一方可见!!

如果在逻辑上不希望共享数组,可以在方法中,把传进来的数组复制一下。

下面的程序演示了对一个数组中的所有工资进行加薪处理。

 1 public class A0410
 2 {
 3     // salary: 工资数组
 4     // per: 加薪的百分点
 5     static void raise(double[] salary, double per){
 6         for(int i=0; i<salary.length; i++){
 7             salary[i] *= 1 + per / 100;
 8         }
 9     }
10     
11     static void show(double[] salary){
12         for(int i=0; i<salary.length; i++){
13             System.out.print(salary[i] + " ");
14         }
15         System.out.println();
16     }
17     
18     public static void main(String[] args){
19         double[] salary = {4520,5311,3766,8600,4700,7125};
20         raise(salary,10);  // 加薪
21         show(salary);  // 显示新的薪资
22     }
23 }

显示一个数组中的全部元素是很常见的任务,我们也可以调用 java.util.Arrays.toString 方法来完成。

 

posted @ 2018-04-09 21:20  可雷曼土  阅读(195)  评论(0编辑  收藏  举报