定义:所谓容器,就是“放东西的东西”。数组可以看作是一种容器,但是数组的元素个数一旦确定就无法改变,这在实际使用中是很大的不足。一般意义上的容器,是指具有自动增长容量能力的存放数据的一种数据结构。在面向对象语言中,这种数据结构本身表达为一个对象。所以才有“放东西的东西”的说法。
Java具有丰富的容器,Java的容器具有丰富的功能和良好的性能。熟悉并能充分有效地利用好容器,是现代程序设计的基本能力。
1.顺序容器
用来存放String的ArrayList类型
ArrayList为容器类型,String为容器内的元素类型
ArrayList<String> notes= new ArrayList<String>;
**容器类有两个类型
- 容器的类型
- 元素的类型**
package notebook;
import java.util.ArrayList;
public class NoteBook {
private ArrayList<String> notes = new ArrayList<String>();
//范型类
private int size=0;
public void add(String s) {
notes.add(s);//按顺序往后加
size++;
//notes.add(10); 错误语句,只能接受String
}
public void add(String s, int location) {
notes.add(location, s);//往某个位置加东西
}
public int getSize() {
return notes.size();//得到容器的元素个数
}
public String getNote(int index) {
return notes.get(index);
}
public void removeNote(int index) {
notes.remove(index);//若越界该函数会抛异常
}
public String[] list(){
String[] a=new String[notes.size()];
// for (int i=0;i<notes.size();i++) {
// a[i]=notes.get(i);
// }
notes.toArray(a);
return a;
}
public static void main(String[] args) {
String[] a =new String[2];
a[0]="first";
a[1]="second";
NoteBook nb=new NoteBook();
nb.add("first");
nb.add("second");
nb.add("third",1);//插到1的位置,second挤到2位置
System.out.println(nb.getSize());
System.out.println(nb.getNote(1));
//System.out.println(nb.getNote(10));越界
nb.removeNote(1);
String[] b=nb.list();
for(String s: b ) {
System.out.println(s);
}
}
}
当用add函数把对象放进容器中去的时候,是把对象的值放进了容器,而非对象本身。
放进去以后,那个对象还在外面。
如果修改了放进去的那个对象,容器中的对象不会发生变化。
如果容器中的对象,之前的对象也不会发生变化。
2.对象数组
当数组的元素的类型是类的时候,数组的每一个元素其实只是对象的管理者而不是对象本身。因此,仅仅创建数组并没有创建其中的每一个对象!
public static void main(String[] args) {
int[] ia =new int[10];
String[] a =new String[10];
for(int i=0;i<a.length;i++) {
a[i]=" "+i;
}
System.out.println(ia[0]+2);
System.out.println(a[0]+"a");
//System.out.println(a[0].length());
// String s=null;
// System.out.println(s.length());
}
for-each循环
public static void main(String[] args) {
ArrayList<String> b=new ArrayList<String>();
b.add("first");
b.add("second");
for(String s:b) {
System.out.println(s);
}
Value[ ] a=new Value[10];
for(int i=0;i<a.length;i++) {
a[i]=new Value();
a[i].set(i);
}
for(Value v:a) {
System.out.println(v.get());//v指向a[i]所管理的对象
v.set(0);//可以操作指向的对象
}
for(Value v:a) {
System.out.println(v.get());
}
// int[] ia =new int[10];
// String[] a =new String[10];
// for(int i=0;i<ia.length;i++) {
// ia[i]=i;
// }
// for(int k:ia) {
// // k++; 没用,取出的每一个元素只是复制品
// System.out.println(k);
// }
// System.out.println(ia[0]+2);
// System.out.println(a[0]+"a");
//System.out.println(a[0].length());
// String s=null;
// System.out.println(s.length());
}
Java本身支持任意数量参数的函数。
方法:在数据类型后添加“…”。
public int[] a(int... i){
return a;
}
public double[] a(double... i){
return a;
}
public String[] a(String... i){
return a;
}
3.集合(Set)
集合就是数学中的集合的概念:所有的元素都具有唯一的值,元素在其中没有顺序。
package notebook;
import java.util.ArrayList;
import java.util.HashSet;
class Value{
private int i;
public void set(int i) {
this.i=i;
}
public int get() {
return i;
}
public String toString() {
return ""+i;
}//任何一个java类通过public String toString()可以用System.out.println(v);
//来主动调用toString函数直接输出对象,用toString函数产生的String来输出
}
public class NoteBook {
private ArrayList<String> notes = new ArrayList<String>();
//范型类
private int size=0;
public void add(String s) {
notes.add(s);//按顺序往后加
size++;
//notes.add(10); 错误语句,只能接受String
}
public void add(String s, int location) {
notes.add(location, s);//往某个位置加东西
}
public int getSize() {
return notes.size();//得到容器的元素个数
}
public String getNote(int index) {
return notes.get(index);
}
public void removeNote(int index) {
notes.remove(index);//若越界该函数会抛异常
}
public String[] list(){
String[] a=new String[notes.size()];
// for (int i=0;i<notes.size();i++) {
// a[i]=notes.get(i);
// }
notes.toArray(a);
return a;
}
public static void main(String[] args) {
Value v =new Value();
v.set(10);
System.out.println(v);//若没有toString()将输出一个奇怪的东西
HashSet<String> s = new HashSet<String>();
s.add("first");
s.add("second");
s.add("first");
// for(String k:s) {
// System.out.println(k);
//}
System.out.println(s);//将容器中所有元素以[..,..,..]形式输出
//ArrayList也可以这样使用
}
}
集合能用get()函数来获得某个位置上的元素吗?
不能,集合没有顺序的概念,也就没有索引的概念,所以get(index)在集合中没有意义。
4.散列表(Hash)
传统意义上的Hash表,是能以int做值,将数据存放起来的数据结构。Java的Hash表可以以任何实现了hash()函数的类的对象做值来存放对象。
e-g:做一个检索美元各分值的英语单词的程序
package coins;
import java.util.HashMap;
import java.util.Scanner;
public class Coin {
private HashMap<Integer,String> coinnames=new HashMap<Integer,String>();
//HashMap中放进去的值都是以一个键和一个值成对放进去的
public Coin() {
//coinnames.put(key, value);//key的类型是Integer,不能是int
//这是一个面向对象的世界,在这些容器中,所有的类型必须是对象而不能是基本类型
//String可以,Integer可以,Integer是int的包裹类型
coinnames.put(1, "penney");//一个包裹类型的变量可以直接接受其基础类型的变量
coinnames.put(10, "dime");
coinnames.put(25, "quarter");
coinnames.put(50, "half-dolar");
//coinnames.put(50, "5毛");若出现两个,则返回的是最后一个,
//其是覆盖,则size大小不变
System.out.println(coinnames.keySet().size());//查找Hash表元素个数
//不能直接通过coinnames.keySet()获得size大小,但keySet可以构建一个数组
//通过这个数组可以获得size大小
System.out.println(coinnames);//全部输出,其有toString()
//对Hash表来说,键是唯一的,
//如果多次放同一个键的值,留下的只有最后一个
for(Integer k:coinnames.keySet()) {
String s=coinnames.get(k);
System.out.println(s);
}//遍历Hash表
}
public String getName(int amount) {
if(coinnames.containsKey(amount)) {//在查找前先判断Value是否存在
//若存在
return coinnames.get(amount);
}
else {//不存在
return "NOT FOUND";
}
}
public static void main(String[] args) {
Scanner in =new Scanner(System.in);
int amount =in.nextInt();
Coin coin=new Coin();
String name =coin.getName(amount);
System.out.println(name);//如果一个HashMap返回null,
//Hash表中所有的Value都一定是对象,所以其返回出来的都是这个类的一个管理者
//如果存在则返回一个有效的东西,若不存在则返回null,表示没有找到
}
}
Hash表习题:
学生成绩的数据结构
如果要写程序表达一个班级的很多个学生的很多门课的成绩,应该如何表达这些数据?
如果我们希望通过学生的姓名,可以找到他的所有的成绩,而每一门课的成绩,是由课程名称和分数构成的。
而如果我们还希望这个程序能找出某一门课的全部学生的成绩应该怎样做呢?
注意,并非所有的学生都参加了所有的课程。
1.一个班级的很多个学生的很多门课的成绩:Class TotalGrade -->HashMap<学生姓名,PersonGrade>;
找出某一门课的全部学生的成绩:Class CourseGrade --> HashMap<课程名称,PersonGrade>;
通过学生的姓名找到他的所有成绩:Class PersonGrade --> HashMap<课程名称,该课成绩>
//Class 课程名称
2.HashMap<Integer,String>用于描述课程代号和课程名称,另一个HashMap<Integer,Integer>用于描述课程代号和课程成绩;两个hash表都在类Student中。
HashMap<String,Student>
String:学生姓名
Student:学生对象
Course :课程对象
class Student{
Course chinese = null;//语文
Course math = null;//数学
...
}
class Course {
String name;//学科名称
int score;//分数
}