容器是现代程序设计非常基础而重要的手段。
所谓容器,就是“放东西的东西”。数组可以看作是一种容器,但是数组的元素个数一旦确定就无法改变,这在实际使用中是很大的不足。一般意义上的容器,是指具有自动增长容量能力的存放数据的一种数据结构。在面向对象语言中,这种数据结构本身表达为一个对象。所以才有“放东西的东西”的说法。
Java具有丰富的容器,Java的容器具有丰富的功能和良好的性能。熟悉并能充分有效地利用好容器,是现代程序设计的基本能力。
我们首先学习的是顺序容器,即放进容器中的对象是按照指定的顺序(放的顺序)排列起来的,而且允许具有相同值的多个对象存在。
在一些书中,将容器(英文为collection或container)翻译为“集合”,由于数学中的集合(Set)也是一种特定的容器类型,我们认为将collection翻译为集合是不恰当的。所以我们只会使用容器一词。
顺序容器相关:
需求分析:如果我们想要创建一个记事本,那么我们对这个记事本会有什么样的要求呢?
1:能存储记录
2:不限制能存储记录的数量
3:能知道已经存储的记录的数量
4:能查看存进去的每一条记录
5:能删除一条记录
6:能列出所有的记录
假设创建类NoteBook,对其进行接口设计。
接口设计:将人机交互与(输入输出)业务逻辑(对数据的处理)分离
1:add(String note);
2:getSize();
3:getNote(int index);
4:removeNote(int index);
5:list();
代码实现:
importjava.util.ArrayList;public classNoteBook {//容器类
private ArrayList notes=new ArrayList();//容器类中自带add()方法
public voidadd(String note) {
notes.add(note);
}//容器类中自带方法,查看记录数量
public intgetSize() {returnnotes.size();
}//容器类中自带方法,得到记录内容
public String getNote(intindex) {returnnotes.get(index);
}//容器类中自带方法,移除第index位记录
public void removeNote(intindex) {
notes.remove(index);
}//容器类中自带方法,将记录的内容传给String数组
publicString[] list() {
String[] a=newString[notes.size()];//for(int i=0;i
notes.toArray(a);returna;
}public static voidmain(String[] args) {
NoteBook nb=newNoteBook();
nb.add("First");
nb.add("Second");
System.out.println(nb.getSize());//使用ArrayList实现For-Each循环
ArrayList a=new ArrayList<>();
a.add("First");
a.add("Second");for(String s:a) {
System.out.println(s);
}
}
}
容器类:ArrayList notes=new ArrayList();
容器类有两个类型:1:容器的类型——ArrayList
2:元素的类型——String
当数组的元素的类型是类的时候,数组的每一个元素其实只是对象的管理者而不是对象本身。因此,仅仅创建数组并没有创建其中的每一个对象!
int类型数组与String类型数组的区别:String创建的对象s只是对象的管理者而不是所有者,即对象数组里面每个元素都是对象的管理者而不是所有者。

思考题:如何设计能传递任意数量参数的函数?
Java中在形参之后加上 ... ,表示参数数量不固定,示例代码如下:
public classMain {public static int sum(int... num) {int sum = 0;for(Integer integer : num) {
sum+=integer;
}returnsum;
}public static voidmain(String[] args) {//TODO Auto-generated method stub
int sum = sum(1,2,3);
System.out.println(sum);
}
}
集合容器(set)相关:
集合就是数学中的集合的概念:所有的元素都具有唯一的值,元素在其中没有顺序。
举例:
importjava.util.HashSet;public classMain {public static voidmain(String[] args) {//TODO Auto-generated method stub
HashSet s=new HashSet();
s.add("First");
s.add("Second");
s.add("First");for(String k:s) {
System.out.println(k);
}//另外一种输出方法
System.out.println(s);
}
}//结果://Second//First//[Second, First]//数学集合(set)的特点之一就是其中的数值具有唯一性且不排序
散列表(Hash)相关:
数字-美元对应
importjava.util.HashMap;importjava.util.Scanner;public classCoins {//在所有的容器里面,所有的类型都必须是对象而不能是基本类型。
private HashMap coinnames=new HashMap();publicCoins() {//HaspMap里面的put方法,Integer表示键位,String表示put进去的内容
coinnames.put(1, "penny");
coinnames.put(5, "niclle");
coinnames.put(10, "dime");
coinnames.put(25, "quarter");
coinnames.put(50, "half-dollar");//对哈希表而言,键key一定是唯一的。同一个键放进去多个值,最终留下的只要最后一次的
coinnames.put(50, "五毛!");
System.out.println(coinnames.keySet().size());//结果为4
System.out.println(coinnames);//结果是:{1=penny, 50=五毛!, 5=niclle, 25=quarter, 10=dime}//Hash表的循环
for(Integer k:coinnames.keySet()) {
String s=coinnames.get(k);
System.out.println(s);
}
}//返回String value
public String getName(intamount) {if(coinnames.containsKey(amount)) {returncoinnames.get(amount);
}else
return "NO FOUND!";
}public static voidmain(String[] args) {
Scanner in=newScanner(System.in);
Coins c=newCoins();int a=in.nextInt();
String name=c.getName(a);
System.out.println(name);
}
}
结果为:
5{1=penny, 50=五毛!, 5=niclle, 25=quarter, 10=dime}
penny
五毛!
niclle
quarter
dime
课后思考题:学生成绩的数据结构
如果要写程序表达一个班级的很多个学生的很多门课的成绩,应该如何表达这些数据?
如果我们希望通过学生的姓名,可以找到他的所有的成绩,而每一门课的成绩,是由课程名称和分数构成的。
而如果我们还希望这个程序能找出某一门课的全部学生的成绩应该怎样做呢?
注意,并非所有的学生都参加了所有的课程。
代码实现:
题目内容:
下图为国内主要城市之间的公路里程:
你的程序要读入这样的一张表,然后,根据输入的两个城市的名称,给出这两个城市之间的里程。
注意:任何两个城市之间的里程都已经给出,不需要计算经第三地中转。
注意:你并不需要去录入上图的数据,数据是在程序输入中给的。
输入格式:
首先,你会读到若干个城市的名字。每个名字都只是一个英文单词,中间不含空格或其他符号。当读到名字为“###”(三个#号)时,表示城市名字输入结束,###并不是一个城市的名字。如果记读到的城市名字的数量为n。
然后,你会读到nxn的一个整数矩阵。第一行的每一个数字,表示上述城市名单中第一个城市依次到另一个城市之间的里程。表中同一个城市之间的里程为0。
最后,你会读到两个城市的名字。
输出格式:
输出这两个城市之间的距离。
输入样例:
HagzouHugzouJigxng ###
01108708
11080994
7089940
Hagzou Jigxng
输出样例:
708
时间限制:500ms内存限制:32000kb
代码实现:
importjava.util.ArrayList;importjava.util.HashMap;importjava.util.Scanner;public classThirdWeenday {//创建一个顺序容器,用来存储城市的名字
private ArrayList city=new ArrayList();//创建一个散列表,里面包含一个散列表。前者表示第i个城市,内部Hash表示第j个城市及城市之间的距离
private HashMap> distance=new HashMap>();private static Scanner in=newScanner(System.in);public voidadd() {
String s;boolean b=true;//判断,当输出城市以###结尾时,不再输入
while(b) {
s=in.next();if(s.equals("###")==true) {
b=false;break;
}
city.add(s);
}//读入距离
for(int i=0;i
HashMap HM=new HashMap();for(int j=0;j
HM.put(city.get(j), dis);
}
distance.put(city.get(i), HM);
}
}//查找两个城市之间的距离
public intgetDistance(String start, String end){int dis = 0;
dis=distance.get(start).get(end);returndis;
}public static voidmain(String[] args) {//TODO Auto-generated method stub//Scanner in=new Scanner(System.in);
ThirdWeenday distan=newThirdWeenday();
distan.add();
String start=in.next();
String end=in.next();
System.out.println(distan.getDistance(start, end));
}
}