《Android游戏开发详解》——第2章,第2.21节对象和基本类型的分组

2.21 对象和基本类型的分组
Android游戏开发详解
Java允许我们把对象和基本类型组织到一起。我们常见的有两种对象,可以用来进行分组,它们是数组和列表。

2.21.1 数组
要表示某种类型的一个数组(或组),我们使用方括号。例如,如果想要整数的一个数组,可以像下面这样声明。

int[] numbers = new int[5];

上面例子中的数字5,表示名为numbers的数组应该有多大。正如上面所声明的,numbers将能够容纳5个整数值。要描述数组的样子,我们可以画一个表,如图2-28所示。

一开始,数组将会有默认值(创建整数数组的时候,默认值是0)。Java允许我们直接为每个索引(或位置)分配数值。数组索引是基于0的,就像字符串中的字符一样。数组的赋值语法如下所示。

numbers[0] = 5;
numbers[1] = 10;
numbers[2] = 15;
numbers[3] = 20;
numbers[4] = 25;

numbers数组将会如图2-29所示。

我们可以使用完全相同的语法来获取这些值。举例如下。

int sum = numbers[0] + numbers[1] + numbers[2] + numbers[3] + numbers[4];
System.out.println(sum)     // will print 75

数组也有缺点。一旦创建了数组,就不能改变其大小。为什么会有这个问题呢?想象一下,你在开发一个射击游戏,其中每次玩家点击鼠标左键,就会有一个Bullet对象添加到一个数组中(表示所有已经发射的子弹)。我们事先不知道需要多少个Bullet。某些玩家可能使用42颗子弹。其他的玩家可能使用刀和手榴弹,甚至不开一枪就完成了关卡。在这种情况下,使用ArrayList通常会更好,它允许我们动态地调整大小以放入更多的对象。

2.21.2 ArrayLists
ArrayLists比数组更加常用,并且你应该知道如何使用它们(以及如何用好它们)。要使用ArrayList,必须首先导入它。

import java.util.ArrayList
创建ArrayLists,就像创建任何其他的对象一样。

ArrayList playerNames = new ArrayList();
我们使用add()方法向一个ArrayList对象中插入对象。

playerNames.add(“Mario”);
playerNames.add(“Luigi”);
...
playerNames.add(“Yoshi”);
你可以看到,这是String对象的一个ArrayList。你可以调用get()方法,使用基于0的索引(注意,用于数组的[]对于ArrayLists无效)从一个ArrayList获取一个对象(在这个例子中,是一个String对象)。

playerNames.get(2);     // will retrieve “Luigi” (kind-of)
理论上讲,我们可以在一个单个的ArrayList中,放置所有的各种类型的对象,而不管其类型是什么;然而,这不是很有用,因为一旦你这么做了,可能不知道某个位置(如索引152)具体是什么类型的对象。如果不知道它是什么类型的对象,你就不知道它有什么方法。看如下所示的例子。

someArrayList.get(152);     // What kind of object is this?

我们从someArrayList提取出第153个对象(记住,索引是基于0的)。问题在于,我们对这个对象一无所知。它可能是一个可口的Sushi对象,又或者甚至是一个危险的Bomb。如果我们这样编写代码,想象一下后果。

Monster hungryOne = new Monster();
Object unknown = someArrayList.get(152);   // The Object is actually a Bomb
hungryOne.eat(unknown);           // hungryOne thinks it’s Sushi
// Boom!

实际上,Java允许我们通过添加标志,来限制ArrayLists只保存某一种类型的对象。

ArrayList<String> playerNames = new ArrayList<String>();
playerNames.add(“Mario”);     // Works!
Bomb b = new Bomb();
playerNames.add(b);       // Gives type-mismatch error

现在,我们知道从playerNames获取的任何对象都是一个String,并且我们可以在其上调用String方法。

// Any object from playerNames will always be a String
String nameZero = playerNames.get(0);
System.out.println(nameZero.length());

2.21.3 对基本类型使用ArrayList
不能直接将基本数据类型插入到一个ArrayList中。实际上,如下所示的代码是不允许的。

ArrayList<int> numbers = new ArrayList<int>(); // not allowed

要绕开这个限制,可以直接使用一个内建的包装类,即每种基本数据类型的对象版本。这包括int所对应的Integer,char所对应的Character,等等。要做到这点,直接创建该ArrayList并声明包装类作为其类型。

ArrayList<Integer> numbers = new ArrayList<Integer>();

这个ArrayList最初的大小为0。

System.out.println(numbers.size());   // Prints zero

接下来,直接调用add()方法,并且传入想要放到ArrayList中的int值。这些值将会自动地包装到一个Integer对象中。

numbers.add(2);
numbers.add(3);
numbers.add(1);

此时,ArrayList看上去如图2-30所示(注意,其长度动态地增长了)。

你可以调用get()方法,传入想要的值的索引,从而获取基本类型值。例如,要取回数字3,让ArrayList给出位于索引1的值。这个值会自动转换为一个int(从包装的Integer对象),因此,你可以将它存储到一个int变量中。
``
int myNum = numbers.get(1);
System.out.println(myNum);   // Prints 3

**2.21.4 对ArrayList使用循环**
在亲眼见到ArrayList的应用之前,你很难认识到它有多么强大,因此,让我们来尝试一个例子。

我们将编写包含了2个类的一个简单的程序。第一个类是我们的进入点,其中,我们存储了main方法并且创建了ArrayList。第二个类将是表示人的一个定制类。

首先,创建一个名为Groups的、新的Java项目。其中,创建一个名为ListTester的新的类,并且给其一个main方法,如程序清单2.25所示。

程序清单2.25 ListTester.java

01 public class ListTester {
02
03    public static void main(String[] args) {
04    
05    }
06
07 }

现在,在同一项目中创建第二个类并将其命名为Person。添加如下所示的变量和方法(参见程序清单2.26)。

程序清单2.26 Person.java

01 public class Person {
02    
03    private String name;
04    private int age;
05
06    public void initialize(String name, int age) {
07        this.name = name;
08        this.age = age;
09    }
10
11    public void describe() {
12        System.out.println("My name is " + name);
13        System.out.println("I am " + age + " years old");
14    }
15
16 }
``
Person类描述了一个新的Person对象的蓝图。特别是,它表明了一个Person对象的状态将由两个实例变量来描述,即name和age。我们没有给name和age默认值,并且,必须调用initialize()方法来提供这些值。一旦Person对象有了一个name和age,我们就可以调用describe()方法,以易于理解、可读的形式打印出这些信息。让我们回到ListTester并且确保可以做到这一点。

程序清单2.27 ListTester.java(更新版本)

1 public class ListTester {
2
3    public static void main(String[] args) {
4        Person p = new Person();
5        p.initialize("Marty", 40);  
6        p.describe();
7    }
8
9 }

我们来一行一行地看一看程序清单2.27:首先创建了Person类的一个名为p的新实例。此时,p有两个实例变量:name和age。这些变量还没有初始化。

接下来,我们调用了initialize()方法,它接受两个值:一个String和一个整数。initialize()方法将会接受这两个值,并且将其赋值给实例变量。

现在,两个实例变量已经初始化了,我们可以通过调用describe()来要求Person对象描述自己。结果如下所示。

My name is Marty
I am 40 years old

现在,我们创建多个Person对象并且将它们组织到一个ArrayList中。修改ListTester类,使其如程序清单2.28所示。

程序清单2.28 创建ArrayList并添加第一个循环

01 import java.util.ArrayList;
02 import java.util.Random;
03
04 public class ListTester {
05
06    public static void main(String[] args) {
07      
08        ArrayList<Person> people = new ArrayList<Person>();
09        Random r = new Random();
10      
11        for (int i = 0; i < 5; i++) {
12            Person p = new Person();
13            p.initialize("Person #" + i, r.nextInt(50));
14            people.add(p);
15        }
16    }
17
18 }

在程序清单2.28中,我们创建了一个新的、名为people的ArrayList,以及一个新的名为r的Random对象。然后,开始了一个for循环,它将运行5次。循环每迭代(重复)一次,我们就创建一个名为p的新的Person对象。用相应的名称(Person #i,其中i从0到4)和一个随机生成的年龄值,来为该Person初始化实例变量。最后,我们把新创建的Person对象添加到ArrayList中(第14行)。循环重复,创建了一个全新的Person,初始化它并且再次添加它。

注意如下所示的代码行。

Person p = new Person();

在循环中创建的任何变量,都只在其相同的迭代中有效,这意味着,该变量仅限于在循环的当前迭代中存在。因此,我们可以在循环的每一次重复中复用变量名p。

每次调用上面的代码,我们都用变量名p创建了一个新的Person。然后,将临时变量p中保存的值,存储到较为持久的、名为people的ArrayList中,以便随后在代码中可以引用每一个新创建的Person对象,而不需要为它们中的每一个分配一个唯一的变量名。

为了看到这是如何工作的,我们可以尝试再次迭代循环,并且调用describe()方法,如程序清单2.29所示(第17行到第20行)。

程序清单2.29 添加第2个循环

01 import java.util.ArrayList;
02 import java.util.Random;
03
04 public class ListTester {
05
06    public static void main(String[] args) {
07      
08        ArrayList<Person> people = new ArrayList<Person>();
09        Random r = new Random();
10      
11        for (int i = 0; i < 5; i++) {
12            Person p = new Person();
13            p.initialize("Person #" + i, r.nextInt(50));
14            people.add(p);
15        }
16      
17        for (int i = 0; i < people.size(); i++) {
18            Person p = people.get(i);
19            p.describe();
20        }
21
22    }
23
24 }

最终的输出如下所示(年龄可能不同,因为是随机生成的)。

My name is Person #0
I am 29 years old
My name is Person #1
I am 1 years old
My name is Person #2
I am 4 years old
My name is Person #3
I am 21 years old
My name is Person #4
I am 47 years old

你可能会问,为什么要将第17行到第20行的循环运行people.size()次而不是5次?两个值是相同的,并且任何一个解决方案都会产生相同的输出;然而,上面的例子是一个更加灵活的循环,因为它并不需要把循环运行的次数直接编码。根据ArrayList people的大小,第二个for循环将运行相应的次数。这意味着,我们可能需要将上一个循环(即向ArrayList添加对象的那个循环)运行的次数从5修改为8,而下面的循环则不需要修改,因为people.size()也会增加为8。

程序清单2.30 迭代8次

01    import java.util.ArrayList;
02    import java.util.Random;
03
04    public class ListTester {
05
06        public static void main(String[] args) {
07      
08            ArrayList<Person> people = new ArrayList<Person>();
09            Random r = new Random();
10      
11            //for (int i = 0; i < 5; i++) {
12            for (int i = 0; i < 8; i++) {  
13                Person p = new Person();
14                p.initialize("Person #" + i, r.nextInt(50));
15                people.add(p);
16            }
17            // people.size() is now 8!
18            for (int i = 0; i < people.size(); i++) {
19                Person p = people.get(i);
20                p.describe();
21            }
22
23        }
24
25    }

最终输出如下所示(年龄可能不同,因为是随机生成的)。

My name is Person #0
I am 27 years old
My name is Person #1
I am 27 years old
My name is Person #2
I am 20 years old
My name is Person #3
I am 28 years old
My name is Person #4
I am 5 years old
My name is Person #5
I am 49 years old
My name is Person #6
I am 2 years old
My name is Person #7
I am 26 years old

上面的示例展示了如何使用循环快速地创建多个对象,并将它们组织到一个ArrayList中。我们还学习到,可以通过一个for循环快速遍历一个ArrayList的所有成员并调用其方法。

时间: 2024-08-02 05:27:30

《Android游戏开发详解》——第2章,第2.21节对象和基本类型的分组的相关文章

《Android游戏开发详解》一第2章 Java基础知识

第2章 Java基础知识 Android游戏开发详解第1章内容完全是成为Java程序员的准备工作.在本章中,你将编写自己的第一个Java程序(包括一款简单的游戏),并学习如何把游戏的角色.加血(power-up)以及其他实体表示为Java对象.

《Android游戏开发详解》——第2章,第2.12节设置和访问对象的状态

2.12 设置和访问对象的状态Android游戏开发详解现在,我们可以访问一个Phone对象了.myPhone表示使用Phone类(class)创建的一个单个的Phone对象(object).它是一个独立的实体,独立于我们将来可能使用蓝图(Phone类)创建的任何其他Phone对象.我们使用实例(instance)这个术语来描述这种现象. 为了更加具体地说明,让我们考虑一下,在工厂中批量生产智能手机的时候会发生什么情况.我们使用相同的蓝图来生产数以千计的设备,而且它们都是彼此独立的.它们可以有自

《Android游戏开发详解》一2.12 设置和访问对象的状态

2.12 设置和访问对象的状态 Android游戏开发详解现在,我们可以访问一个Phone对象了.myPhone表示使用Phone类(class)创建的一个单个的Phone对象(object).它是一个独立的实体,独立于我们将来可能使用蓝图(Phone类)创建的任何其他Phone对象.我们使用实例(instance)这个术语来描述这种现象. 为了更加具体地说明,让我们考虑一下,在工厂中批量生产智能手机的时候会发生什么情况.我们使用相同的蓝图来生产数以千计的设备,而且它们都是彼此独立的.它们可以有

《Android游戏开发详解》——第2章,第2.2节设置开发机器

2.2 设置开发机器 Android游戏开发详解 在开始编写简单点的Java程序和构建令人兴奋的游戏之前,我们必须在自己的机器上安装一些软件.然而,这个过程有点枯燥且颇费时间,但是,为了让第一个程序开始运行,这些代价都是值得的. 2.2.1 安装Eclipse 我们将利用一个集成开发环境(Integrated Development Environment,IDE)来编写Java/Android应用程序.IDE是一种工具的名称,它能够帮助我们轻松地编写.构建和运行程序. 我们将要使用的IDE叫作

《Android游戏开发详解》——第1章,第1.9节训练到此结束

1.9 训练到此结束Android游戏开发详解如果你已经学到了这里,恭喜你!你已经完成了进入美丽的.复杂的并且偶尔令人沮丧的编程世界的第一步.但是,在编写一些Java代码之前,你还不能自称为一名Java程序员.因此,快打开你的计算机并且开始学习第2章,在那里,我们要构建一些Java程序了.

《Android游戏开发详解》——第2章,第2.8节对象的基础知识

2.8 对象的基础知识Android游戏开发详解我们已经应用了第1章中介绍过的概念来编写和运行一些非常简单的Java程序.接下来,我们将把注意力转向对象,它使得我们能够编写更加复杂和强大的程序. 什么是对象?以你看待现实世界中的物体的方式来思考Java对象,这么做是有帮助的.对象所拥有的属性,我们称之为状态(state)和行为(behavior). 让我们以手机为例子.你的手机拥有状态,它可能是黑色的,并且可能打开了电源开关.这些属性可以帮助我们描述手机以形成其状态.手机还会有行为.它可能能够播

《Android游戏开发详解》——第3章,第3.7节里程碑

3.7 里程碑Android游戏开发详解介绍完这个示例,我们也就结束了本书的第3章和第1部分.如果你一直在学习,那么应该已经了解了编程的基础知识,掌握了Java基础并且学习了高级的面向对象设计概念.Java游戏开发就在前面,它肯定是一个巨大的挑战甚至会带来更多的兴奋. 在我们继续学习之前,我想要提醒你,Java是一种庞大的编程语言.尽管我已经试图尽可能地向你介绍在开发Java和Android游戏的时候可能会遇到的所有概念,但我还是没办法公正地对待这门语言.如果你有兴趣学习Java的更多知识以及更

《Android游戏开发详解》——第2章,第2.1节面向对象编程

2.1 面向对象编程Android游戏开发详解Java是一种面向对象编程语言.在面向对象的范型中,我们以对象的形式来表示数据,以帮助我们形成概念并沟通思路.例如,在构建视频共享Web应用程序的时候,我们可能要创建一个User对象来表示每个用户账户(及其所有的数据,例如,用户名.密码.上传的视频等).使用一个Video对象来表示每一个上传的视频,其中的很多视频都组织到一个Playlist对象中. 考虑到整洁.健壮的代码更容易阅读和理解,面向对象编程允许我们将相关的数据组织到一起.为了了解这一思路,

《Android游戏开发详解》——第2章,第2.14节隐藏变量

2.14 隐藏变量Android游戏开发详解注意,到目前位置,我们能够以两种不同的方式来修改Phone对象的状态.我们能够使用点运算符直接访问其变量,并且分配显式的值:还能够使用Phone对象提供的行为来间接地修改Phone对象的状态. 如果能够直接深入到myPhone对象,取出其信息并修改,我们说对象的变量是暴露的.从现在开始,我们将禁止暴露变量,基于很多原因,暴露变量可能会有问题. 例如,如果某人试图给一个变量分配一个非法的(或者不符合逻辑的)值,会怎么样呢?如下的代码对Java程序来说可能

《Android游戏开发详解》——第2章,第2.6节构建一个简单的计算器程序

2.6 构建一个简单的计算器程序Android游戏开发详解现在,我们已经尝到了甜头,让我们回过头来看看第1章介绍过的一些概念,并且构建一个简单的计算器程序.让我们给出一些动手实践的指导,来构建一个新的Java程序.请记住如下的主要步骤. ① 创建一个新的Java项目(将其命名为SecondProject). ② 在src文件夹中创建一个新的类(将其命名为SimpleCalculator). ③ 创建一个main方法. 如果任何时候你碰到困难,应该参考前面的小节.一旦按照上面的步骤进行,应该会看到