Java 3 对象容器
Ref:
什么是泛型
Java 容器 & 泛型(1):认识容器
3.1 顺序容器
我们首先学习的是顺序容器,即放进容器中的对象是按照指定的顺序(放的顺序)排列起来的,而且允许具有相同值的多个对象存在。
3.1.1 记事本程序的设计
需求分析:
- 无限存储记录(用数组不合适)
- 已存储数量
- 查看记录
- 删除记录
- 列出所有记录
类的接口设计(使用层次):
add(String note);
getSize();
getnote(int index);
removeNote(int index);
list();
将人机交互(输入输出)与业务逻辑(数据处理)分开处理。
3.1.2 泛型容器类
ArrayList <String> notes=new ArrayList<String>();
容器类有两个类型:
- 容器的类型ArrayList
- 元素的类型<String>
package notebook;
import java.util.ArrayList;
public class NoteBook {
private ArrayList <String> notes=new ArrayList<String>();
public void add(String s) {
notes.add(s);//ArrayList类自带的函数
}
public void add(String s,int location) {
notes.add(location,s);//插入到当前位置,其他元素按顺序后移一位
}
public int getSize() {
return notes.size();//ArrayList类自带的函数
}
public String getnote(int index) {
return notes.get(index);
}
public void removeNote(int index) {
notes.remove(index);
}
public String[] list() {//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
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));//输出0位置上的元素
System.out.println(nb.getnote(1));
nb.removeNote(1);
String[] a=nb.list();
for (String s:a) {
System.out.println(s);
}
}
}
了解ArrayList内部的函数可以省很多力气。
3.2 对象数组
当数组的元素的类型是类的时候,数组的每一个元素其实只是对象的管理者而不是对象本身。因此,仅仅创建数组并没有创建其中的每一个对象!
int数组和String数组的区别
String a=new String[10];
每个格子都是String类的管理者
对象数组中,每个元素都是对象的管理者而非对象本身。
FOR-EACH可以用于数组的遍历,
FOR-EACH中对象数组和普通数组有区别:
普通数组:
普通数组FOR-EACH
int[] inta=new int[10];
for(int k:inta)
{
k=1;
}
这里k=0不会起到任何作用,inta数组的值还是初始的0。
因为FOR-EACH执行过程:通过数组的下标将元素逐个取出,并赋值给变量,相当于: int k = ia[i];
对象数组:
定义一个类value
class Value{
private int i;
public void set(int i) {this.i=i;}
public int get() {return i;}
}
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());
}
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());
}
在FOR-EACH循环中v.set(0);
后,Value数组的值都变为0了。
3.3 集合容器(HashSet)
集合就是数学中的集合的概念:所有的元素都具有唯一的值,无重复元素,元素在其中没有顺序。
HashSet <String> s=new HashSet <String>();
import java.util.ArrayList;
import java.util.HashSet;
ArrayList<String> a=new ArrayList<String>();
a.add("first");
a.add("second");
a.add("first");
// for(String s:a)
// {
// System.out.println(s);
// }
System.out.println(a);//可以直接输出Set
System.out.println("----华丽的分割线----");
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);
Console:
[first, second, first]
----华丽的分割线----
[first, second]
System.out.println(s);
为什么可以直接输出呢?
class Value{
private int i;
public void set(int i) {this.i=i;}
public int get() {return i;}
public String toString() {return ""+i;}
}
public static void main(String[] args) {
Value v=new Value();
v.set(10);
System.out.println(v);
}
Console:
10
如果没有public String toString() {return ""+i;}
则会错误地输出clock.Value@15db9742
类里面有了 toString()函数的话,在System.out.println时会自动调用toString()函数来输出。
ArrayList和HashSet类里肯定有这个功能的函数。
3.4 散列表(HashMap)
传统意义上的Hash表,是能以int做值,将数据存放起来的数据结构。
Java的Hash表可以以任何实现了hash()函数的类的对象做值来存放对象。
import java.util.HashMap;
import java.util.Scanner;
public class Coin {
private HashMap<Integer,String> coinnames=new HashMap<Integer,String>();
//所有的类型必须是对象,不能使基本类型,比如这里要用integer,不能用int,integer是int的包裹类型
public Coin()
{
coinnames.put(1, "penny");//包裹类型的变量可以直接接收对应的基础类型的变量
coinnames.put(10, "dime");
coinnames.put(25, "quarter");
coinnames.put(15, "harf-dollar");
}
public String getName(int amount)
{
if(coinnames.containsKey(amount))
{
return coinnames.get(amount);
}
else
{
return "not found";
}
}
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);
in.close();
}
}
10
4
{1=penny, 25=quarter, 10=dime, 15=五毛}
dime
public Coin()
{
coinnames.put(1, "penny");//包裹类型的变量可以直接接收对应的基础类型的变量
coinnames.put(10, "dime");
coinnames.put(25, "quarter");
coinnames.put(15, "harf-dollar");
coinnames.put(15, "五毛"); //键是唯一的
System.out.println(coinnames.keySet().size()); //coinnames的大小
System.out.println(coinnames); //直接输出
System.out.println("-----遍历-----");
for(Integer k:coinnames.keySet())
{
String s=coinnames.get(k);
System.out.println(s);
}
System.out.println("--------------");
}
- 这里HashMap<Integer,String>里面只能用Integer,不能用int。
-
coinnames.put(15, "五毛");
后,键值对就变成<15,五毛> -
coinnames.keySet().size()
HashSet没有输出size的函数,可以用keySet()获得键的集合,通过集合获得HashSet的size。 -
System.out.println(coinnames);
HashSet和ArrayList一样,也可以直接输出的。 -
哈希表的遍历:通过keySet()来获得值。
泛型容器