第3周 对象容器
本文是观看翁恺老师《面向对象程序设计Java》时所做
视频来源-中国大学Mooc网
文章目录
3.1 对象容器
容器是现代程序设计非常基础而重要的手段。
所谓容器,就是“放东西的东西”。数组可以看作是一种容器,但是数组的元素个数一旦确定就无法改变,这在实际使用中是很大的不足。一般意义上的容器,是指具有自动增长容量能力的存放数据的一种数据结构。在面向对象语言中,这种数据结构本身表达为一个对象。所以才有“放东西的东西”的说法。
Java具有丰富的容器,Java的容器具有丰富的功能和良好的性能。熟悉并能充分有效地利用好容器,是现代程序设计的基本能力。
我们首先学习的是顺序容器,即放进容器中的对象是按照指定的顺序(放的顺序)排列起来的,而且允许具有相同值的多个对象存在。
在一些书中,将容器(英文为collection或container)翻译为“集合”,由于数学中的集合(Set)也是一种特定的容器类型,我们认为将collection翻译为集合是不恰当的。所以我们只会使用容器一词。
3.1.1 记事本的例子
-
记事本需要的功能
-
接口设计
界面UI和业务逻辑一定要分离!
NoteBook.java
package notebook;
import java.lang.reflect.Array;
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;
// }
}
public class NoteBook {
private ArrayList<String> notes = new ArrayList<String>();
public void add(String s) {
notes.add(s);
}
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) {
// TODO Auto-generated method stub
// int[] ia = new int[10];
// for( int i=0; i<ia.length; i++)
// {
// ia[i] = i;
// }
// for( int k : ia )
// {
// System.out.println(k);
// }
Value v = new Value();
v.set(10);
System.out.println(v);
ArrayList<String> a = new ArrayList<>();
a.add("first");
a.add("second");
a.add("first");
for( String s : a)
{
System.out.println(s);
}
System.out.println(a);
System.out.println("_____________");
HashSet<String> s = new HashSet<>();
s.add("first");
s.add("second");
s.add("first");
for( String k : s )
{
System.out.println(k);
}
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.set(0);
// }
// for( Value v: a )
// {
// System.out.println(v.get());
// }
// 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].length());
// String s = null;
// System.out.println(s.length());
// NoteBook nb = new NoteBook();
// nb.add("first");
// nb.add("second");
// nb.add("third", 1);
// System.out.println(nb.getSize());
// System.out.println(nb.getNote(0));
// System.out.println(nb.getNote(1));
// nb.removeNote(1);
// String[] a = nb.list();
// for(String s:a)
// {
// System.out.println(s);
// }
}
}
3.1.2 泛型容器类(泛型类)
private ArrayList<String> notes = new ArrayList<String>();
容器类型有两个类型:
- 容器的类型
- 元素的类型
3.1.3 ArrayList的操作
- 下标从0开始
- remove
- get
- add
- size()
- toArray() 将数组添加进容器
#究竟把什么放进容器里去了?
当我们用add函数把对象放进容器中去的时候,究竟是把什么放进了容器?放进去的是对象本身吗?放进去以后,那个对象还在外面吗?如果修改了放进去的那个对象,容器中的对象会变化吗?写点代码来验证自己的猜测吧。
容器里元素的类型是对象,对象是引用类型,那存放在容器里的内容相当于对象的变量,也就是对象的管理者。
3.2 对象数组
当数组的元素的类型是类的时候,数组的每一个元素其实只是对象的管理者而不是对象本身。因此,仅仅创建数组并没有创建其中的每一个对象!
这里的String
类型数组只是保存每个类的管理者.
对象数组中的每个元素都是对象的管理者而非对象本身
当你创建一个对象数组时,还需要创建对应的对象。
3.2.2 对象数组的for-each循环
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.set(0);
}
for( Value v: a )
{
System.out.println(v.get());
}
String[] a = new String[10];
for( int i=0; i<a.length; i++)
{
a[i] = ""+i;
}
容器类for-each也可以用!
如何设计能传递任意数量参数的函数?
public static double max(double... values) {
double max = Double.MIN_VALUE;
for (double v : values)
if (v > max)
max = v;
return max;
}
在形式参数的地方 使用了 double... values ,需要注意的时,采用这种方式values必须作为最后一个参数
printf()在实现时就采用了这种方式。
调用方式:
Class.max(1.2,5.2,6.5) //可接受任意数量的double值
Class.max(new double[]{1.2,5.2,6.5}) //等价
double[] d = {1.2,5.2,6.5};
Class.max(d)
3.3 集合数组(Set)
- 集合容器
集合就是数学中的集合的概念:所有的元素都具有唯一的值,元素在其中没有顺序。
HashSet<String> s = new HashSet<>();
s.add("first");
s.add("second");
s.add("first");
for( String k : s )
{
System.out.println(k);
}
System.out.println(s);
集合能用get()函数来获得某个位置上的元素吗?
集合里的元素不是按照顺序存储的
3.4 散列表(Hash)
传统意义上的Hash表,是能以int做值,将数据存放起来的数据结构。Java的Hash表可以以任何实现了hash()函数的类的对象做值来存放对象。
Hash表是非常有用的数据结构,熟悉它,充分使用它,往往能起到事半功倍的效果。
Coins.java
package coins;
import java.util.HashMap;
import java.util.Scanner;
public class Coin {
private HashMap<Integer, String> coinnames = new HashMap<>();
public Coin(){
coinnames.put(1, "penny");
coinnames.put(10, "demo");
coinnames.put(25, "quarter");
coinnames.put(50, "half-dolar");
coinnames.put(50, "Îåë");
System.out.println(coinnames.keySet().size());
System.out.println(coinnames);
for( Integer k : coinnames.keySet() )
{
String s = coinnames.get(k);
System.out.println(s);
}
}
public String getName( int amount ){
return coinnames.get(amount);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
int amount = in.nextInt();
Coin coin = new Coin();
String name = coin.getName(amount);
System.out.println(name);
}
}
学生成绩的数据结构
如果要写程序表达一个班级的很多个学生的很多门课的成绩,应该如何表达这些数据?
如果我们希望通过学生的姓名,可以找到他的所有的成绩,而每一门课的成绩,是由课程名称和分数构成的。
而如果我们还希望这个程序能找出某一门课的全部学生的成绩应该怎样做呢?
注意,并非所有的学生都参加了所有的课程。
package score;
import java.util.HashMap;
class Scores {
private HashMap<String, HashMap<String, Double>> scores = new HashMap<String, HashMap<String, Double>>();
public void addScores(String name, String course, double score)
{
if (scores.containsKey(name))
{
scores.get(name).put(course, score);
}
else
{
HashMap<String, Double> temp = new HashMap<String, Double>();
temp.put(course, score);
scores.put(name, temp);
}
}
public String getScore (String name)
{
HashMap<String, Double> temp = new HashMap<String, Double>();
for (String k : scores.keySet())
{
if (k == name)
{
temp = scores.get(name);
break;
}
}
return name+":"+temp.toString();
}
public String getAllScores (String course)
{
HashMap<String, Double> temp = new HashMap<String,Double>();
for (String k :scores.keySet())
{
if (scores.get(k).containsKey(course))
{
temp.put(k, scores.get(k).get(course));
}
}
return course+":"+ temp.toString();
}
public String toString()
{
String temp = "";
for (String k: scores.keySet())
temp+=(k+":"+scores.get(k).toString());
return temp;
}
public static void main(String[] args) {
Scores scores = new Scores();
scores.addScores("张三", "Chinese", 100);
scores.addScores("张三", "Math", 100);
scores.addScores("李四", "Chinese", 95);
scores.addScores("李四", "Math", 95);
System.out.println(scores.getAllScores("Chinese"));
System.out.println(scores.getScore("张三"));
System.out.println(scores);
}
}