1、课程名称:JAVA类集
?类集的作用、Collection、Map、Iterator、ListIterator、List、Set、Enumeration、二叉树算法
?JAVA SE的最重要四块知识:面向对象、类集、JAVA IO、数据库编程
2、知识点
2.1、上次课程的主要知识点
?1、?IO操作
??? BufferedReader:一次性读取数据
??? PrintStream:打印流
??? 字节流:InputStream、OutputStream
??? File类
?2、?对象序列化
2.2、本次预计讲解的知识点
?1、?类集的作用
?2、?单值集合:Collection、List、Set
?3、?二元偶集合:Map
?4、?输出:Iterator、ListIterator、Enumeration
?5、?类集的作用
3、具体内容
3.1、类集的作用
?类集:就是一个动态的对象数组。
?对象数组:可以保存一组对象,但是其本身有长度的限制。
?类集可以保存一组对象,但是此保存没有长度的限制。
?在JAVA中类集的操作都在java.util包中,本身也分为两种操作形式:
?1、?存放单值的类集,最大的接口是Collection,每次可以存放一个值。但是其下又分为两个子接口:
???? List接口:表示可以重复,插入的顺序即为输出顺序
???? Set接口:不能够有重复元素
???? List接口在实际中应用较为广泛
??主要操作方法:
???? 添加一个对象:public boolean add(Object obj)
???? 清空里面的所有内容:public void clear() ;
???? 测试集合中是否包含指定元素:boolean contains(Object o)
???? 判断集合是否为空:public boolean isEmpty()
???? 从集合中删除指定内容:public boolean remove(Object o)
???? 取得集合中大小:public int size()
???? 将集合变为对象数组:public Object[] toArray()
???? 将集合变为Iterator实例:public Iterator<E> iterator()
??对于整个Collection集合,只允许从前向后输出,没有从后向前输出的功能。
?讨论:
??? 是使用Collection好,还是使用List或Set好呢?
?2、?存放一对值的类型:Map集合
value???? key
??? 通过key可以找到value
?3、?Collection与Map的作用:
??? Collection主要用于数据输出上
??? Map主要用于数据查找上
3.2、List接口
?List为Collection的子接口,如果要想使用此接口,则必须通过其子类为其实例化,从运行效果中可以发现,在List中可以有重复的内容。
?List接口拥有比Collection接口中更多的方法,主要以下几个常用方法:
??? 在指定位置上加入元素:public void add(int index,Object obj)
??? 返回指定位置的元素:public Object get(int ind)
??? 返回ListIterator实例:public ListIterator<E> listIterator()
3.2.1、常用子类
1、 ArrayList:是一个新的类,是在JDK 1.2推出之后才有的。本身属于异步处理。性能高,但是不属于线程的安全处理。只允许使用Iterator接口输出。
2、?Vector:是一个旧的类,是在JDK 1.0时推出的。本身属于同步处理。性能相对较低,但是属于线程安全的,因为使用了同步。可以使用Iterator或Enumeration(使用类本身)输出
3.2.2、Vector类
?Vetor也是经过发展之后不断改良,在最早就已经实现了动态数组的功能,之后之后又增加了List接口的实现,所以在整个代码之中对于Vector本身也有自己的一个特性:
?? 增加元素:public void addElement(Object obj),此功能与add()一样。
?? 枚举输出:public Enumeration<E> elements()
?Vector类中还有一个堆栈的类 —— Stack,此类实现了先进后出的功能。
?Stack中主要有以下两个方法:
??? 入栈:public Object push(Object item)
??? 出栈:public Object pop()
3.2.3、使用List操作(ArrayList)
例如:以下代码演示了ArrayList的作用
import java.util.* ;
public class ColDemo01{
?public static void main(String args[]){
??// Collection all = new ArrayList() ;
??List all = new ArrayList() ;
??all.add("A") ;
??all.add("A") ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??System.out.println(all) ;
?}
};
例如:使用clear()方法清空里面的全部内容
import java.util.* ;
public class ColDemo02{
?public static void main(String args[]){
??// Collection all = new ArrayList() ;
??List all = new ArrayList() ;
??all.add("A") ;
??all.add("A") ;
??// 清空全部的内容
??all.clear() ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??System.out.println(all) ;
?}
};
例如:测试contains()方法,查找指定内容
import java.util.* ;
public class ColDemo03{
?public static void main(String args[]){
??// Collection all = new ArrayList() ;
??List all = new ArrayList() ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??System.out.println(all.contains("A")) ;
??System.out.println(all.contains("X")) ;
?}
};
例如:验证集合是否为空
import java.util.* ;
public class ColDemo04{
?public static void main(String args[]){
??// Collection all = new ArrayList() ;
??List all = new ArrayList() ;
??System.out.println(all.isEmpty()) ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??System.out.println(all.isEmpty()) ;
?}
};
例如:以下代码演示了remove()作用
import java.util.* ;
public class ColDemo05{
?public static void main(String args[]){
??// Collection all = new ArrayList() ;
??List all = new ArrayList() ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??all.remove("B") ;
??System.out.println(all) ;
?}
};
例如:将集合变为对象数组输出
import java.util.* ;
public class ColDemo06{
?public static void main(String args[]){
??// Collection all = new ArrayList() ;
??List all = new ArrayList() ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??Object str[] = all.toArray() ;
??for(int i=0;i<all.size();i++){
???String s = (String)str[i] ;
???System.out.println(s) ;
??}
?}
};
之前的所有代码在编译的时候都出现了以下的提示:
注意: ColDemo01.java 使用了未经检查或不安全的操作。
注意: 要了解详细信息,请使用 -Xlint:unchecked 重新编译。
?那么这样的错误提示,是因为在JDK 1.5之后加入了泛型的操作。因为类集中本身是使用Object进行接收的,而且接收的时候牵扯到转型问题,那么如果不指定泛型的话,则里面肯定可以加入各种类型的数据,那么在转型会出现类型转换异常。如下代码所示:
import java.util.* ;
public class ColDemo10{
?public static void main(String args[]){
??// Collection all = new ArrayList() ;
??List all = new ArrayList() ;
??all.add("A") ;
??all.add(1) ;
??all.add('2') ;
??Iterator iter = all.iterator() ;
??while(iter.hasNext()){
???String str = (String)iter.next() ;
???if("C".equals(str)){
????// 使用了Iterator中的删除语法。
????iter.remove() ;
???}
??}
??System.out.println(all) ;
?}
};
?那么此时,就可以加入泛型进行错误的回避,加入之后,集合中只能有一种类型,当然,在实际中集合中的数据也只有一种类型。
import java.util.* ;
public class ColDemo11{
?public static void main(String args[]){
??// Collection<String> all = new ArrayList<String>() ;
??List<String> all = new ArrayList<String>() ;
??all.add("A") ;
??all.add(1) ;
??all.add('2') ;
??Iterator<String> iter = all.iterator() ;
??while(iter.hasNext()){
???String str = iter.next() ;
???System.out.println(str) ;
??}
?}
};
?以上加入了泛型操作之后,在编译的时候以上代码就会出现错误提示:
ColDemo11.java:7: 找不到符号
符号: 方法 add(int)
位置: 接口 java.util.List<java.lang.String>
??????????????? all.add(1) ;
?????????????????? ^
ColDemo11.java:8: 找不到符号
符号: 方法 add(char)
位置: 接口 java.util.List<java.lang.String>
??????????????? all.add('2') ;
?????????????????? ^
2 错误
?所以,此时,代码只能按如下样式编写:
import java.util.* ;
public class ColDemo11{
?public static void main(String args[]){
??// Collection<String> all = new ArrayList<String>() ;
??List<String> all = new ArrayList<String>() ;
??all.add("A") ;
??all.add("B") ;
??Iterator<String> iter = all.iterator() ;
??while(iter.hasNext()){
???String str = iter.next() ;
???System.out.println(str) ;
??}
?}
};
例如:使用List进行由后向前的输出
import java.util.* ;
public class ColDemo12{
?public static void main(String args[]){
??List<String> all = new ArrayList<String>() ;
??all.add("A") ;
??all.add("B") ;
??all.add(1,"X") ;
??all.add(0,"H") ;
??all.add(2,"Y") ;
??for(int i=all.size()-1;i>=0;i--){
???System.out.println(all.get(i)) ;
??}
?}
};
3.2.4、使用List操作(Vector)
例如:使用Vector完成以上的操作
import java.util.* ;
public class ColDemo14{
?public static void main(String args[]){
??List<String> all = new Vector<String>() ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??all.add("D") ;
??all.add("E") ;
??Iterator<String> liter = all.iterator() ;
??while(liter.hasNext()){
???System.out.print(liter.next()+"、") ;
??}
?}
};
?可以发现,整个程序与之前没有任何的区别。
3.2.5、使用Stack操作
例如:入栈和出栈
import java.util.* ;
public class ColDemo16{
?public static void main(String args[]){
??Stack<String> s = new Stack<String>() ;
??s.push("A") ;
??s.push("B") ;
??s.push("C") ;
??System.out.println(s.pop()) ;
??System.out.println(s.pop()) ;
??System.out.println(s.pop()) ;
??System.out.println(s.pop()) ;
?}
};
?如果栈的内容已经空了,再继续出栈的话,则肯定出现以下的错误:
Exception in thread "main" java.util.EmptyStackException
3.3、Set接口
?与List接口不同的是Set接口中本身不能有任何的重复元素。
?与List接口不同的是Set接口中并没有对Collection进行扩充,也就是说,Set只是比Collection接口增加了一个不能重复的功能。
?JAVA中通过类的HashCode和equals两个方法来确定是否是同一个对象。
3.3.1、常用子类(理解)
?1、?HashSet:是散列存放的,无序
?2、?TreeSet:是排序的,使用Comparable接口排序(二叉树排序),如果使用Comparable的时候里面的所有字段都要进行比较,否则如果有若干个字段相同,而其他字段没有比较的话,系统会认为是重复的内容,而去掉。
?? 二叉树(Binary Tree),三种遍历方式:
??? 前序遍历:根-左-右
??? 中序遍历:左-根-右
??? 后序遍历:左-右-根
3.3.2、使用Set操作(HashSet)
例如:观察HashSet使用
import java.util.* ;
public class ColDemo17{
?public static void main(String args[]){
??Set<String> all = new HashSet<String>() ;
??all.add("A") ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??all.add("D") ;
??all.add("E") ;
??Iterator<String> iter = all.iterator() ;
??while(iter.hasNext()){
???System.out.println(iter.next()) ;
??}
?}
};
3.3.3、使用Set操作(TreeSet)
例如:观察TreeSet功能
import java.util.* ;
public class ColDemo18{
?public static void main(String args[]){
??Set<String> all = new TreeSet<String>() ;
??all.add("A") ;
??all.add("X") ;
??all.add("B") ;
??all.add("D") ;
??all.add("Q") ;
??all.add("Q") ;
??Iterator<String> iter = all.iterator() ;
??while(iter.hasNext()){
???System.out.println(iter.next()) ;
??}
?}
};
?那么,如果现在给定了一个类的若干对象,如果使用TreeSet存放是否可以?
import java.util.* ;
class Person{
?private String name ;
?private int age ;
?public Person(String name,int age){
??this.name = name ;
??this.age = age ;
?}
?public String toString(){
??return "姓名;" + this.name + ",年龄;" + this.age ;
?}
};
public class ColDemo19{
?public static void main(String args[]){
??Set<Person> all = new TreeSet<Person>() ;
??all.add(new Person("张三",30)) ;
??all.add(new Person("李四",31)) ;
??all.add(new Person("王五",32)) ;
??Iterator<Person> iter = all.iterator() ;
??while(iter.hasNext()){
???System.out.println(iter.next()) ;
??}
?}
};
?以上代码运行的时候出现了以下的错误:
Exception in thread "main" java.lang.ClassCastException: Person
?类型转换异常,因为TreeSet本身是带排序功能的,如果现在要对一个对象进行排序,则必须指定对象的排序规则,排序规则通过比较器 —— Comparable完成。
import java.util.* ;
class Person implements Comparable<Person>{
?private String name ;
?private int age ;
?public Person(String name,int age){
??this.name = name ;
??this.age = age ;
?}
?public String toString(){
??return "姓名;" + this.name + ",年龄;" + this.age ;
?}
?public int compareTo(Person per){
??if(this.age>per.age){
???return -1 ;
??}else if(this.age<per.age){
???return 1 ;
??}else{
???return 0 ;
??}
?}
};
public class ColDemo20{
?public static void main(String args[]){
??Set<Person> all = new TreeSet<Person>() ;
??all.add(new Person("张三",30)) ;
??all.add(new Person("李四",31)) ;
??all.add(new Person("王五",32)) ;
??Iterator<Person> iter = all.iterator() ;
??while(iter.hasNext()){
???System.out.println(iter.next()) ;
??}
?}
};
观察TreeSet的问题:
?? 题目:设计一个学生类,此类包含姓名、年龄、成绩,产生一个对象数组,要求按成绩由高到低排序、如果成绩相等,则按年龄由低到高排序。
?通过java.util.Arrays类可以排序。public static void sort(Object[] a)
?发现以上的操作可以对一个对象数组进行排序
import java.util.* ;
class Student implements Comparable<Student>{
?private String name ;
?private int age ;
?private float score ;
?public Student(String name,int age,float score){
??this.name = name ;
??this.age = age ;
??this.score = score ;
?}
?public String toString(){
??return name + "\t\t" + age + "\t\t" + score ;
?}
?public int compareTo(Student stu){
??if(this.score>stu.score){
???return -1 ;
??}else if(this.score<stu.score){
???return 1 ;
??}else{
???if(this.age>stu.age){
????return 1 ;
???}else if(this.age<stu.age){
????return -1 ;
???}else{
????return this.name.compareTo(stu.name) ;
???}
??}
?}
};
public class ColDemo34{
?public static void main(String args[]){
??Set<Student> s = new TreeSet<Student>() ;
??s.add(new Student("张三",20,90.0f)) ;
??s.add(new Student("李四",22,90.0f)) ;
??s.add(new Student("王五",20,99.0f)) ;
??s.add(new Student("赵六",20,70.0f)) ;
??s.add(new Student("孙七",22,100.0f)) ;
??s.add(new Student("赵九",22,100.0f)) ;
??Iterator<Student> iter = s.iterator() ;
??while(iter.hasNext()){
???System.out.println(iter.next()) ;
??}
?}
};
3.3.4、二叉树排序(理解)
?对于整个JAVA来说所有的排序操作都是以Comparable展开的,所以现在重点观察Comparable。
?以下代码全部使用String为例。
例如:使用Comparable接收String对象
public class ColDemo22{
?public static void main(String args[]){
??Comparable c = "abc" ;
??System.out.println(c) ;
?}
};
分析:
?1、?所有对象打印的时候调用的都是toString()
?2、?String类中已经覆写toString()
?3、?String是Object的子类。
?4、?如果直接打印Comparable接口对象,调用的是toString()方法,但是此时此对象是通过String实例化的,所以肯定使的是String中已经被覆写toString()方法。
?对于JAVA中可以使用以下的方式规定出二叉树的排序方式:
class BinaryTree{
?class Node{
??// 具体的内容
??private Comparable data ;
??// 保存左子树
??private Node left ;
??// 保存右子树
??private Node right ;
??public void addNode(Node newNode){
???// 要确定是放在左子树还是右子树
???if(newNode.data.compareTo(this.data)<0){
????// 放在左子树
????if(this.left==null){
?????this.left = newNode ;
????}else{
?????this.left.addNode(newNode) ;
????}
???}
???if(newNode.data.compareTo(this.data)>0){
????// 放在左子树
????if(this.right==null){
?????this.right = newNode ;
????}else{
?????this.right.addNode(newNode) ;
????}
???}
??}
??public void printNode(){
???// 先输出左子树
???if(this.left!=null){
????this.left.printNode() ;
???}
???// 输出根节点
???System.out.println(this.data) ;
???// 输出右子树
???if(this.right!=null){
????this.right.printNode() ;
???}
??}
?};
?// 确定根元素
?private Node root ;
?public void add(Comparable data){
??Node newNode = new Node() ;
??newNode.data = data ;
??if(root==null){
???// 第一个元素,设置成根元素
???root = newNode ;
??}else{
???// 如果此语句没有执行的话,则必须确定好是放在左子树还是右子树
???root.addNode(newNode) ;
??}
?}
?public void print(){
??this.root.printNode() ;
?}
};
public class ColDemo23{
?public static void main(String args[]){
??BinaryTree bt = new BinaryTree() ;
??bt.add("C") ;
??bt.add("X") ;
??bt.add("A") ;
??bt.add("S") ;
??bt.add("O") ;
??bt.print() ;
?}
};
3.4、Iterator接口
3.4.1、接口的主要用处
?Iterator是一个迭代输出接口。
?Iterator接口定义:
??? 判断下一个元素是否有内容:public boolean hasNext()
??? 取出内容:public Object next() ;
??? 从集合中删除元素:public void remove() ;
例如:使用Iterator输出Collection(List)中的内容
import java.util.* ;
public class ColDemo07{
?public static void main(String args[]){
??// Collection all = new ArrayList() ;
??List all = new ArrayList() ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??Iterator iter = all.iterator() ;
??while(iter.hasNext()){
???String str = (String)iter.next() ;
???System.out.println(str) ;
??}
?}
};
3.4.2、删除元素的说明
?在List和Iterator上都有remove方法。
?在使用Iterator迭代输出的时候,不能修改List中的内容,如果一旦修改,则肯定会出现错误。
例如:以下代码在迭代输出的时候使用了List中的remove方法。
import java.util.* ;
public class ColDemo08{
?public static void main(String args[]){
??// Collection all = new ArrayList() ;
??List all = new ArrayList() ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??Iterator iter = all.iterator() ;
??while(iter.hasNext()){
???String str = (String)iter.next() ;
???if("C".equals(str)){
????// 使用了List中的删除语法。
????all.remove(str) ;
???}
??}
?}
};
?以上代码运行时出现了错误:
Exception in thread "main" java.util.ConcurrentModificationException
??????? at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
??????? at java.util.AbstractList$Itr.next(Unknown Source)
??????? at ColDemo08.main(ColDemo08.java:11)
?同样的代码,现在直接使用Iterator中的删除方法完成:
import java.util.* ;
public class ColDemo09{
?public static void main(String args[]){
??// Collection all = new ArrayList() ;
??List all = new ArrayList() ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??Iterator iter = all.iterator() ;
??while(iter.hasNext()){
???String str = (String)iter.next() ;
???if("C".equals(str)){
????// 使用了Iterator中的删除语法。
????iter.remove() ;
???}
??}
??System.out.println(all) ;
?}
};
3.4.3、子接口 —— ListIterator
?Iterator本身只支持由前向后的输出,并不支持由后向前,那么其有一个子接口 —— ListIterator,此接口可以将内容从前向后,也可以从后向前,但是必须注意的是:必须先由前向后输出完之后,才能由后向前输出。只有List接口的对象才可以使用此种方法。
?ListIterator中的主要方法:
??? 判断是否有下一个内容:public boolean hasNext()
??? 取出下一个元素:public Object next()
??? 判断是否有上一个元素:public boolean hasPrevious();
??? 取出上一个元素:public Object previous() ;
??? 本身ListIterator也是支持泛型的
例如:以下代码演示了ListIterator的作用
import java.util.* ;
public class ColDemo13{
?public static void main(String args[]){
??List<String> all = new ArrayList<String>() ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??all.add("D") ;
??all.add("E") ;
??ListIterator<String> liter = all.listIterator() ;
??System.out.println(" ============== 由前向后输出 ==================") ;
??while(liter.hasNext()){
???System.out.print(liter.next()+"、") ;
??}
??System.out.println("") ;
??System.out.println(" ============== 由后向前输出 ==================") ;
??while(liter.hasPrevious()){
???System.out.print(liter.previous()+"、") ;
??}
?}
};
3.4、Enumeration接口
?是最早的迭代输出接口,其本身的功能和Iterator类似,但是因为其出现较早,而且代码本身存在安全问题,所以现在使用较少,但是对于一些原有的系统中的若干方法,还是只能使用Enumeration输出。
?Enumerationi接口的定义:
??? 判断是否有下一个元素:public boolean hasMoreElements()
??? 取出元素:public Object nextElement()
例如:使用Enumeration输出Vector中的内容
import java.util.* ;
public class ColDemo15{
?public static void main(String args[]){
??Vector<String> all = new Vector<String>() ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??all.add("D") ;
??all.add("E") ;
??Enumeration<String> enu = all.elements() ;
??while(enu.hasMoreElements()){
???System.out.print(enu.nextElement()+"、") ;
??}
?}
};
3.5、foreach输出(了解)
?提供了比Iterator更简单的输出语法,但是是在JDK 1.5之后才增加的。
语法格式:
for(类型 对象:集合){
?进行对象的操作
}
例如:验证foreach语法
import java.util.* ;
class Person implements Comparable<Person>{
?private String name ;
?private int age ;
?public Person(String name,int age){
??this.name = name ;
??this.age = age ;
?}
?public String toString(){
??return "姓名;" + this.name + ",年龄;" + this.age ;
?}
?public int compareTo(Person per){
??if(this.age>per.age){
???return -1 ;
??}else if(this.age<per.age){
???return 1 ;
??}else{
???return 0 ;
??}
?}
};
public class ColDemo21{
?public static void main(String args[]){
??Set<Person> all = new TreeSet<Person>() ;
??all.add(new Person("张三",30)) ;
??all.add(new Person("李四",31)) ;
??all.add(new Person("王五",32)) ;
??for(Person p:all){
???System.out.println(p) ;
??}
?}
};
3.6、Map接口
?与之前Collection不同的是Map接口可以存放一对值。
?Map与Set一样,本身不能有任何重复的内容(key不能重复)。
?主要操作方法如下;
??? 向集合中插入一组数据:public V put(K key,V value)
??? 根据key取出value:public V get(Object key)
?在Map中因为其组成较为特殊,所以本身不直接支持Iterator输出。
Set实例? entrySet() ???? 步骤:Map 区分key和value。? Map.Entry实例 ? Iterator ?
??? Map.Entry:是Map的内部接口
???|- 得到key:public K getKey()
|- 得到value:public V getValue()
??? 操作方法:
???|- 将全部的Map变为Set集合:public Set<Map.Entry<K,V>> entrySet()
???|- 将全部的key变为Set集合:public Set<K> keySet()
???|- 将全部的value变为Collection集合:public Collection<V> values()
3.6.1、常用子类
?1、?HashMap:是一个新的类,是在JDK 1.2之后推出的,属于异步处理方式。
?2、?Hashtable:是一个旧的类,是在JDK 1.0时推出,属于同步处理方式
?3、?TreeMap:按照key排序,同样key所在的类必须实现Comparable接口
3.6.2、Hashtable子类 —— Properties
?与Hashtable不同的是Properties主要操作的内容为字符串,表示的是属性操作。
?Properties的主要方法:
??? 设置属性:public Object setProperty(String key, String value)
??? 取得属性:
???|- public String getProperty(String key):根据key找到value,没找到返回null。
|- public String getProperty(String key,String defaultValue):如果没有找到,则指定默认值。
??? 保存属性到文件:public void store(OutputStream out,String comments) throws IOException
??? 从文件中读取内容:public void load(InputStream inStream) throws IOException
??? 把文件保存成XML样式:
???|- public void storeToXML(OutputStream os,String comment) throws IOException
??? 从XML样式的文件之中读取属性:
???|- public void loadFromXML(InputStream in) throws IOException,
??????????????????????? InvalidPropertiesFormatException
3.6.3、Map操作(HashMap)
例如:通过HashMap验证Map的使用
import java.util.* ;
public class ColDemo24{
?public static void main(String arg[]){
??Map<String,String> m = new HashMap<String,String>() ;
??m.put("zhangsan","123456") ;
??m.put("lisi","234567") ;
??m.put("wangwu","345678") ;
??String str = m.get("zhangsan") ;
??System.out.println(str) ;
??System.out.println(m.get("xxx")) ;
?}
};
3.6.4、Map操作(Hashtable)
import java.util.* ;
public class ColDemo25{
?public static void main(String arg[]){
??Map<String,String> m = new Hashtable<String,String>() ;
??m.put("zhangsan","123456") ;
??m.put("lisi","234567") ;
??m.put("wangwu","345678") ;
??String str = m.get("zhangsan") ;
??System.out.println(str) ;
??System.out.println(m.get("xxx")) ;
?}
};
3.6.5、Map操作(TreeMap)
import java.util.* ;
public class ColDemo26{
?public static void main(String arg[]){
??Map<String,String> m = new TreeMap<String,String>() ;
??m.put("zhangsan","123456") ;
??m.put("lisi","234567") ;
??m.put("wangwu","345678") ;
??String str = m.get("zhangsan") ;
??System.out.println(str) ;
??System.out.println(m.get("xxx")) ;
?}
};
3.6.6、Map操作(输出)
1、?使用Iterator输出Map中的全部数据(格式是固定的)
?? public Set<Map.Entry<K,V>> entrySet()
import java.util.* ;
public class ColDemo27{
?public static void main(String arg[]){
??Map<String,String> m = new TreeMap<String,String>() ;
??m.put("zhangsan","123456") ;
??m.put("lisi","234567") ;
??m.put("wangwu","345678") ;
??Set<Map.Entry<String,String>> all = m.entrySet() ;
??Iterator<Map.Entry<String,String>> iter = all.iterator() ;
??while(iter.hasNext()){
???Map.Entry me = iter.next() ;
???System.out.println(me.getKey() + " --> " + me.getValue()) ;
??}
?}
};
2、?将Map中全部的key输出
import java.util.* ;
public class ColDemo28{
?public static void main(String arg[]){
??Map<String,String> m = new TreeMap<String,String>() ;
??m.put("zhangsan","123456") ;
??m.put("lisi","234567") ;
??m.put("wangwu","345678") ;
??Set<String> all = m.keySet() ;
??Iterator<String> iter = all.iterator() ;
??while(iter.hasNext()){
???System.out.println(iter.next()) ;
??}
?}
};
3、?将Map中全部的value输出
import java.util.* ;
public class ColDemo29{
?public static void main(String arg[]){
??Map<String,String> m = new TreeMap<String,String>() ;
??m.put("zhangsan","123456") ;
??m.put("lisi","234567") ;
??m.put("wangwu","345678") ;
??Collection<String> all = m.values() ;
??Iterator<String> iter = all.iterator() ;
??while(iter.hasNext()){
???System.out.println(iter.next()) ;
??}
?}
};
3.6.7、Map操作(问题)
例如:定义一个Person类,里面有name和age属性,之后在Map中保存一个person对象。
import java.util.* ;
class Person{
?private String name ;
?private int age ;
?public Person(String name,int age){
??this.name = name ;
??this.age = age ;
?}
?public String toString(){
??return "姓名:" + this.name + ",年龄:" + this.age ;
?}
};
public class ColDemo30{
?public static void main(String args[]){
??Map<String,Person> m = new HashMap<String,Person>() ;
??m.put("zhangsan",new Person("张三",30)) ;
??System.out.println(m.get("zhangsan")) ;
?}
};
?以上的运行结果,可以发现内容已经查找出来了。如果现在换个方式,使用Person对象表示张三呢?
import java.util.* ;
class Person{
?private String name ;
?private int age ;
?public Person(String name,int age){
??this.name = name ;
??this.age = age ;
?}
?public String toString(){
??return "姓名:" + this.name + ",年龄:" + this.age ;
?}
};
public class ColDemo31{
?public static void main(String args[]){
??Map<Person,String> m = new HashMap<Person,String>() ;
??m.put(new Person("张三",30),"zhangsan") ;
??System.out.println(m.get(new Person("张三",30))) ;
?}
};
?从运行结果,发现,里面没有任何的内容,返回一个“null”。此时再修改代码:
import java.util.* ;
class Person{
?private String name ;
?private int age ;
?public Person(String name,int age){
??this.name = name ;
??this.age = age ;
?}
?public String toString(){
??return "姓名:" + this.name + ",年龄:" + this.age ;
?}
};
public class ColDemo32{
?public static void main(String args[]){
??Map<Person,String> m = new HashMap<Person,String>() ;
??Person p = new Person("张三",30) ;
??m.put(p,"zhangsan") ;
??System.out.println(m.get(p)) ;
?}
};
?以上可以找到代号。
?从以上代码中可以发现问题:
??? 如果使用字符串作为key,就算是匿名对象也是可以找得到
??? 如果自己编写了一个key,则如果使用匿名对象则无法找到。
?因为在对象上有一个对象自己的编码,那么如果要想使用此编码,则必须在对象所在的类中覆写Object类中的hashCode()方法。
import java.util.* ;
class Person{
?private String name ;
?private int age ;
?public Person(String name,int age){
??this.name = name ;
??this.age = age ;
?}
?public String toString(){
??return "姓名:" + this.name + ",年龄:" + this.age ;
?}
?public boolean equals(Object obj){
??if(this==obj){
???return true ;
??}
??if(!(obj instanceof Person)){
???return false ;
??}
??Person p = (Person)obj ;
??if(this.name.equals(p.name)&&this.age==p.age){
???return true ;
??}else{
???return false ;
??}
?}
?public int hashCode(){
??// 正常来说,应该为hashCode的产生自己定义一个公式
??return this.age * this.name.hashCode() ;
?}
};
public class ColDemo33{
?public static void main(String args[]){
??Map<Person,String> m = new HashMap<Person,String>() ;
??m.put(new Person("张三",30),"zhangsan") ;
??System.out.println(m.get(new Person("张三",30))) ;
?}
};
3.6.8、Properties操作
1、?向Properties中设置属性,并取得属性
import java.util.* ;
public class ColDemo35{
?public static void main(String args[]){
??Properties pro = new Properties() ;
??pro.setProperty("BJ","BeiJing") ;
??pro.setProperty("NJ","NanJing") ;
??pro.setProperty("SH","ShangHai") ;
??System.out.println(pro.getProperty("BJ")) ;
??System.out.println(pro.getProperty("XJ")) ;
??System.out.println(pro.getProperty("XJ","nofound")) ;
?}
};
2、?将全部的属性保存在普通文件之中
import java.util.* ;
import java.io.* ;
public class ColDemo36{
?public static void main(String args[]) throws Exception{
??Properties pro = new Properties() ;
??pro.setProperty("BJ","BeiJing") ;
??pro.setProperty("NJ","NanJing") ;
??pro.setProperty("SH","ShangHai") ;
??pro.store(new FileOutputStream(new File("e:\\pro.ini")),"AREA") ;
?}
};
3、?从文件中读取属性
import java.util.* ;
import java.io.* ;
public class ColDemo37{
?public static void main(String args[]) throws Exception{
??Properties pro = new Properties() ;
??pro.load(new FileInputStream(new File("e:\\pro.ini"))) ;
??System.out.println(pro.getProperty("BJ")) ;
?}
};
4、?将属性按照XML样式的风格进行保存
import java.util.* ;
import java.io.* ;
public class ColDemo38{
?public static void main(String args[]) throws Exception{
??Properties pro = new Properties() ;
??pro.setProperty("BJ","BeiJing") ;
??pro.setProperty("NJ","NanJing") ;
??pro.setProperty("SH","ShangHai") ;
??pro.storeToXML(new FileOutputStream(new File("e:\\pro.xml")),"AREA") ;
?}
};
5、?将属性从XML中读取出来
import java.util.* ;
import java.io.* ;
public class ColDemo39{
?public static void main(String args[]) throws Exception{
??Properties pro = new Properties() ;
??pro.loadFromXML(new FileInputStream(new File("e:\\pro.xml"))) ;
??System.out.println(pro.getProperty("BJ")) ;
?}
};
?现在操作属性的时候基本上都是以XML样式为准。
3.7、实例
3.7.1、实例一
?一个人有多本书,一本书属于一个人。
package org.lxh.demo1;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
class Person {
?private String name;
?private int age;
?private List<Book> allBooks;
?public Person() {
??this.allBooks = new ArrayList<Book>();
?}
?public Person(String name, int age) {
??this();
??this.name = name;
??this.age = age;
?}
?public String getName() {
??return name;
?}
?public void setName(String name) {
??this.name = name;
?}
?public int getAge() {
??return age;
?}
?public void setAge(int age) {
??this.age = age;
?}
?public List<Book> getAllBooks() {
??return allBooks;
?}
?public void setAllBooks(List<Book> allBooks) {
??this.allBooks = allBooks;
?}
}
class Book {
?private String title;
?private Person person;
?public Book(String title) {
??super();
??this.title = title;
?}
?public String getTitle() {
??return title;
?}
?public void setTitle(String title) {
??this.title = title;
?}
?public Person getPerson() {
??return person;
?}
?public void setPerson(Person person) {
??this.person = person;
?}
}
public class Demo01 {
?public static void main(String[] args) {
??Person per = new Person("张三", 30);
??Book b1 = new Book("JAVA");
??Book b2 = new Book("C");
??Book b3 = new Book("NET");
??per.getAllBooks().add(b1);
??per.getAllBooks().add(b2);
??per.getAllBooks().add(b3);
??b1.setPerson(per);
??b2.setPerson(per);
??b3.setPerson(per);
??System.out.println("姓名:" + per.getName() + ",年龄:" + per.getAge());
??Iterator<Book> iter = per.getAllBooks().iterator();
??while (iter.hasNext()) {
???System.out.println("\t|- " + iter.next().getTitle());
??}
?}
}
3.7.2、实例二
?一个学生可以选多个课程,一个课程可以多个学生参加。
package org.lxh.demo2;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
class Student {
?private String name;
?private List<Course> allCourses;
?public Student() {
??this.allCourses = new ArrayList<Course>();
?}
?public Student(String name) {
??this();
??this.name = name;
?}
?public String getName() {
??return name;
?}
?public void setName(String name) {
??this.name = name;
?}
?public List<Course> getAllCourses() {
??return allCourses;
?}
?public void setAllCourses(List<Course> allCourses) {
??this.allCourses = allCourses;
?}
}
class Course {
?private String name;
?public List<Student> allStudents;
?public Course() {
??this.allStudents = new ArrayList<Student>();
?}
?public Course(String name) {
??this();
??this.name = name;
?}
?public String getName() {
??return name;
?}
?public void setName(String name) {
??this.name = name;
?}
?public List<Student> getAllStudents() {
??return allStudents;
?}
?public void setAllStudents(List<Student> allStudents) {
??this.allStudents = allStudents;
?}
}
public class Demo02 {
?public static void main(String[] args) {
??Student s1 = new Student("张三");
??Student s2 = new Student("李四");
??Student s3 = new Student("王五");
??Student s4 = new Student("赵六");
??Student s5 = new Student("孙七");
??Course c1 = new Course("JAVA");
??Course c2 = new Course("Oracle");
??// 设置关系
??s1.getAllCourses().add(c1);
??c1.getAllStudents().add(s1);
??s2.getAllCourses().add(c1);
??c1.getAllStudents().add(s2);
??s3.getAllCourses().add(c1);
??c1.getAllStudents().add(s3);
??s4.getAllCourses().add(c2);
??c2.getAllStudents().add(s4);
??s5.getAllCourses().add(c2);
??c2.getAllStudents().add(s5);
??s1.getAllCourses().add(c2);
??c2.getAllStudents().add(s1);
??s2.getAllCourses().add(c2);
??c2.getAllStudents().add(s2);
??System.out.println("学生:" + s1.getName());
??Iterator<Course> iter1 = s1.getAllCourses().iterator();
??while (iter1.hasNext()) {
???System.out.println("\t|- " + iter1.next().getName());
??}
??System.out.println("---------------------------------");
??System.out.println("课程:" + c2.getName());
??Iterator<Student> iter2 = c2.getAllStudents().iterator();
??while (iter2.hasNext()) {
???System.out.println("\t|- " + iter2.next().getName());
??}
?}
}
4、总结
1、?Collection(保存单个对象)
?? List:允许有重复元素,拥有更多的操作方法
??|- ArrayList:新的、异步处理
??|- Vector:旧的, 同步处理,支持Iterator和Enumeration两种输出
???|- Stack:入栈、出栈
?? Set:不允许有重复元素,靠hashCode和equals方法来区分重复元素
??|- HashSet:无序
??|- TreeSet:有序、按照Comparable指定的规则排序
?? 常用方法:add()、iterator()、remove
2、?Map(保存一对对象)
?? HashMap:新的类,异步处理
?? Hashtable:旧的类,同步处理
??|- Properties(属性操作),可以将属性保存在文件之中
?? TreeMap:排序操作类,此类按key排序,使用Comparable完成
?? 主要方法:put、get、entrySet
?? Map不能直接使用Iterator输出,必须转换成Set,通过Map.Entry分离key和value
3、?Iterator
?? 输出接口,只要是类集都使用此接口输出,一般情况下很少有删除代码出现
?? 主要方法:
??|- 判断是否有下一个元素:public boolean hasNext()
??|- 取出当前元素:public Object next()
?? 子接口:ListIterator
??|- 双向输出,但是此接口只能通过List实例化
4、?Enumeration接口
?? 最早的输出接口,现在部分代码上依然使用
?类集的作用、Collection、Map、Iterator、ListIterator、List、Set、Enumeration、二叉树算法
?JAVA SE的最重要四块知识:面向对象、类集、JAVA IO、数据库编程
2、知识点
2.1、上次课程的主要知识点
?1、?IO操作
??? BufferedReader:一次性读取数据
??? PrintStream:打印流
??? 字节流:InputStream、OutputStream
??? File类
?2、?对象序列化
2.2、本次预计讲解的知识点
?1、?类集的作用
?2、?单值集合:Collection、List、Set
?3、?二元偶集合:Map
?4、?输出:Iterator、ListIterator、Enumeration
?5、?类集的作用
3、具体内容
3.1、类集的作用
?类集:就是一个动态的对象数组。
?对象数组:可以保存一组对象,但是其本身有长度的限制。
?类集可以保存一组对象,但是此保存没有长度的限制。
?在JAVA中类集的操作都在java.util包中,本身也分为两种操作形式:
?1、?存放单值的类集,最大的接口是Collection,每次可以存放一个值。但是其下又分为两个子接口:
???? List接口:表示可以重复,插入的顺序即为输出顺序
???? Set接口:不能够有重复元素
???? List接口在实际中应用较为广泛
??主要操作方法:
???? 添加一个对象:public boolean add(Object obj)
???? 清空里面的所有内容:public void clear() ;
???? 测试集合中是否包含指定元素:boolean contains(Object o)
???? 判断集合是否为空:public boolean isEmpty()
???? 从集合中删除指定内容:public boolean remove(Object o)
???? 取得集合中大小:public int size()
???? 将集合变为对象数组:public Object[] toArray()
???? 将集合变为Iterator实例:public Iterator<E> iterator()
??对于整个Collection集合,只允许从前向后输出,没有从后向前输出的功能。
?讨论:
??? 是使用Collection好,还是使用List或Set好呢?
?2、?存放一对值的类型:Map集合
value???? key
??? 通过key可以找到value
?3、?Collection与Map的作用:
??? Collection主要用于数据输出上
??? Map主要用于数据查找上
3.2、List接口
?List为Collection的子接口,如果要想使用此接口,则必须通过其子类为其实例化,从运行效果中可以发现,在List中可以有重复的内容。
?List接口拥有比Collection接口中更多的方法,主要以下几个常用方法:
??? 在指定位置上加入元素:public void add(int index,Object obj)
??? 返回指定位置的元素:public Object get(int ind)
??? 返回ListIterator实例:public ListIterator<E> listIterator()
3.2.1、常用子类
1、 ArrayList:是一个新的类,是在JDK 1.2推出之后才有的。本身属于异步处理。性能高,但是不属于线程的安全处理。只允许使用Iterator接口输出。
2、?Vector:是一个旧的类,是在JDK 1.0时推出的。本身属于同步处理。性能相对较低,但是属于线程安全的,因为使用了同步。可以使用Iterator或Enumeration(使用类本身)输出
3.2.2、Vector类
?Vetor也是经过发展之后不断改良,在最早就已经实现了动态数组的功能,之后之后又增加了List接口的实现,所以在整个代码之中对于Vector本身也有自己的一个特性:
?? 增加元素:public void addElement(Object obj),此功能与add()一样。
?? 枚举输出:public Enumeration<E> elements()
?Vector类中还有一个堆栈的类 —— Stack,此类实现了先进后出的功能。
?Stack中主要有以下两个方法:
??? 入栈:public Object push(Object item)
??? 出栈:public Object pop()
3.2.3、使用List操作(ArrayList)
例如:以下代码演示了ArrayList的作用
import java.util.* ;
public class ColDemo01{
?public static void main(String args[]){
??// Collection all = new ArrayList() ;
??List all = new ArrayList() ;
??all.add("A") ;
??all.add("A") ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??System.out.println(all) ;
?}
};
例如:使用clear()方法清空里面的全部内容
import java.util.* ;
public class ColDemo02{
?public static void main(String args[]){
??// Collection all = new ArrayList() ;
??List all = new ArrayList() ;
??all.add("A") ;
??all.add("A") ;
??// 清空全部的内容
??all.clear() ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??System.out.println(all) ;
?}
};
例如:测试contains()方法,查找指定内容
import java.util.* ;
public class ColDemo03{
?public static void main(String args[]){
??// Collection all = new ArrayList() ;
??List all = new ArrayList() ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??System.out.println(all.contains("A")) ;
??System.out.println(all.contains("X")) ;
?}
};
例如:验证集合是否为空
import java.util.* ;
public class ColDemo04{
?public static void main(String args[]){
??// Collection all = new ArrayList() ;
??List all = new ArrayList() ;
??System.out.println(all.isEmpty()) ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??System.out.println(all.isEmpty()) ;
?}
};
例如:以下代码演示了remove()作用
import java.util.* ;
public class ColDemo05{
?public static void main(String args[]){
??// Collection all = new ArrayList() ;
??List all = new ArrayList() ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??all.remove("B") ;
??System.out.println(all) ;
?}
};
例如:将集合变为对象数组输出
import java.util.* ;
public class ColDemo06{
?public static void main(String args[]){
??// Collection all = new ArrayList() ;
??List all = new ArrayList() ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??Object str[] = all.toArray() ;
??for(int i=0;i<all.size();i++){
???String s = (String)str[i] ;
???System.out.println(s) ;
??}
?}
};
之前的所有代码在编译的时候都出现了以下的提示:
注意: ColDemo01.java 使用了未经检查或不安全的操作。
注意: 要了解详细信息,请使用 -Xlint:unchecked 重新编译。
?那么这样的错误提示,是因为在JDK 1.5之后加入了泛型的操作。因为类集中本身是使用Object进行接收的,而且接收的时候牵扯到转型问题,那么如果不指定泛型的话,则里面肯定可以加入各种类型的数据,那么在转型会出现类型转换异常。如下代码所示:
import java.util.* ;
public class ColDemo10{
?public static void main(String args[]){
??// Collection all = new ArrayList() ;
??List all = new ArrayList() ;
??all.add("A") ;
??all.add(1) ;
??all.add('2') ;
??Iterator iter = all.iterator() ;
??while(iter.hasNext()){
???String str = (String)iter.next() ;
???if("C".equals(str)){
????// 使用了Iterator中的删除语法。
????iter.remove() ;
???}
??}
??System.out.println(all) ;
?}
};
?那么此时,就可以加入泛型进行错误的回避,加入之后,集合中只能有一种类型,当然,在实际中集合中的数据也只有一种类型。
import java.util.* ;
public class ColDemo11{
?public static void main(String args[]){
??// Collection<String> all = new ArrayList<String>() ;
??List<String> all = new ArrayList<String>() ;
??all.add("A") ;
??all.add(1) ;
??all.add('2') ;
??Iterator<String> iter = all.iterator() ;
??while(iter.hasNext()){
???String str = iter.next() ;
???System.out.println(str) ;
??}
?}
};
?以上加入了泛型操作之后,在编译的时候以上代码就会出现错误提示:
ColDemo11.java:7: 找不到符号
符号: 方法 add(int)
位置: 接口 java.util.List<java.lang.String>
??????????????? all.add(1) ;
?????????????????? ^
ColDemo11.java:8: 找不到符号
符号: 方法 add(char)
位置: 接口 java.util.List<java.lang.String>
??????????????? all.add('2') ;
?????????????????? ^
2 错误
?所以,此时,代码只能按如下样式编写:
import java.util.* ;
public class ColDemo11{
?public static void main(String args[]){
??// Collection<String> all = new ArrayList<String>() ;
??List<String> all = new ArrayList<String>() ;
??all.add("A") ;
??all.add("B") ;
??Iterator<String> iter = all.iterator() ;
??while(iter.hasNext()){
???String str = iter.next() ;
???System.out.println(str) ;
??}
?}
};
例如:使用List进行由后向前的输出
import java.util.* ;
public class ColDemo12{
?public static void main(String args[]){
??List<String> all = new ArrayList<String>() ;
??all.add("A") ;
??all.add("B") ;
??all.add(1,"X") ;
??all.add(0,"H") ;
??all.add(2,"Y") ;
??for(int i=all.size()-1;i>=0;i--){
???System.out.println(all.get(i)) ;
??}
?}
};
3.2.4、使用List操作(Vector)
例如:使用Vector完成以上的操作
import java.util.* ;
public class ColDemo14{
?public static void main(String args[]){
??List<String> all = new Vector<String>() ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??all.add("D") ;
??all.add("E") ;
??Iterator<String> liter = all.iterator() ;
??while(liter.hasNext()){
???System.out.print(liter.next()+"、") ;
??}
?}
};
?可以发现,整个程序与之前没有任何的区别。
3.2.5、使用Stack操作
例如:入栈和出栈
import java.util.* ;
public class ColDemo16{
?public static void main(String args[]){
??Stack<String> s = new Stack<String>() ;
??s.push("A") ;
??s.push("B") ;
??s.push("C") ;
??System.out.println(s.pop()) ;
??System.out.println(s.pop()) ;
??System.out.println(s.pop()) ;
??System.out.println(s.pop()) ;
?}
};
?如果栈的内容已经空了,再继续出栈的话,则肯定出现以下的错误:
Exception in thread "main" java.util.EmptyStackException
3.3、Set接口
?与List接口不同的是Set接口中本身不能有任何的重复元素。
?与List接口不同的是Set接口中并没有对Collection进行扩充,也就是说,Set只是比Collection接口增加了一个不能重复的功能。
?JAVA中通过类的HashCode和equals两个方法来确定是否是同一个对象。
3.3.1、常用子类(理解)
?1、?HashSet:是散列存放的,无序
?2、?TreeSet:是排序的,使用Comparable接口排序(二叉树排序),如果使用Comparable的时候里面的所有字段都要进行比较,否则如果有若干个字段相同,而其他字段没有比较的话,系统会认为是重复的内容,而去掉。
?? 二叉树(Binary Tree),三种遍历方式:
??? 前序遍历:根-左-右
??? 中序遍历:左-根-右
??? 后序遍历:左-右-根
3.3.2、使用Set操作(HashSet)
例如:观察HashSet使用
import java.util.* ;
public class ColDemo17{
?public static void main(String args[]){
??Set<String> all = new HashSet<String>() ;
??all.add("A") ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??all.add("D") ;
??all.add("E") ;
??Iterator<String> iter = all.iterator() ;
??while(iter.hasNext()){
???System.out.println(iter.next()) ;
??}
?}
};
3.3.3、使用Set操作(TreeSet)
例如:观察TreeSet功能
import java.util.* ;
public class ColDemo18{
?public static void main(String args[]){
??Set<String> all = new TreeSet<String>() ;
??all.add("A") ;
??all.add("X") ;
??all.add("B") ;
??all.add("D") ;
??all.add("Q") ;
??all.add("Q") ;
??Iterator<String> iter = all.iterator() ;
??while(iter.hasNext()){
???System.out.println(iter.next()) ;
??}
?}
};
?那么,如果现在给定了一个类的若干对象,如果使用TreeSet存放是否可以?
import java.util.* ;
class Person{
?private String name ;
?private int age ;
?public Person(String name,int age){
??this.name = name ;
??this.age = age ;
?}
?public String toString(){
??return "姓名;" + this.name + ",年龄;" + this.age ;
?}
};
public class ColDemo19{
?public static void main(String args[]){
??Set<Person> all = new TreeSet<Person>() ;
??all.add(new Person("张三",30)) ;
??all.add(new Person("李四",31)) ;
??all.add(new Person("王五",32)) ;
??Iterator<Person> iter = all.iterator() ;
??while(iter.hasNext()){
???System.out.println(iter.next()) ;
??}
?}
};
?以上代码运行的时候出现了以下的错误:
Exception in thread "main" java.lang.ClassCastException: Person
?类型转换异常,因为TreeSet本身是带排序功能的,如果现在要对一个对象进行排序,则必须指定对象的排序规则,排序规则通过比较器 —— Comparable完成。
import java.util.* ;
class Person implements Comparable<Person>{
?private String name ;
?private int age ;
?public Person(String name,int age){
??this.name = name ;
??this.age = age ;
?}
?public String toString(){
??return "姓名;" + this.name + ",年龄;" + this.age ;
?}
?public int compareTo(Person per){
??if(this.age>per.age){
???return -1 ;
??}else if(this.age<per.age){
???return 1 ;
??}else{
???return 0 ;
??}
?}
};
public class ColDemo20{
?public static void main(String args[]){
??Set<Person> all = new TreeSet<Person>() ;
??all.add(new Person("张三",30)) ;
??all.add(new Person("李四",31)) ;
??all.add(new Person("王五",32)) ;
??Iterator<Person> iter = all.iterator() ;
??while(iter.hasNext()){
???System.out.println(iter.next()) ;
??}
?}
};
观察TreeSet的问题:
?? 题目:设计一个学生类,此类包含姓名、年龄、成绩,产生一个对象数组,要求按成绩由高到低排序、如果成绩相等,则按年龄由低到高排序。
?通过java.util.Arrays类可以排序。public static void sort(Object[] a)
?发现以上的操作可以对一个对象数组进行排序
import java.util.* ;
class Student implements Comparable<Student>{
?private String name ;
?private int age ;
?private float score ;
?public Student(String name,int age,float score){
??this.name = name ;
??this.age = age ;
??this.score = score ;
?}
?public String toString(){
??return name + "\t\t" + age + "\t\t" + score ;
?}
?public int compareTo(Student stu){
??if(this.score>stu.score){
???return -1 ;
??}else if(this.score<stu.score){
???return 1 ;
??}else{
???if(this.age>stu.age){
????return 1 ;
???}else if(this.age<stu.age){
????return -1 ;
???}else{
????return this.name.compareTo(stu.name) ;
???}
??}
?}
};
public class ColDemo34{
?public static void main(String args[]){
??Set<Student> s = new TreeSet<Student>() ;
??s.add(new Student("张三",20,90.0f)) ;
??s.add(new Student("李四",22,90.0f)) ;
??s.add(new Student("王五",20,99.0f)) ;
??s.add(new Student("赵六",20,70.0f)) ;
??s.add(new Student("孙七",22,100.0f)) ;
??s.add(new Student("赵九",22,100.0f)) ;
??Iterator<Student> iter = s.iterator() ;
??while(iter.hasNext()){
???System.out.println(iter.next()) ;
??}
?}
};
3.3.4、二叉树排序(理解)
?对于整个JAVA来说所有的排序操作都是以Comparable展开的,所以现在重点观察Comparable。
?以下代码全部使用String为例。
例如:使用Comparable接收String对象
public class ColDemo22{
?public static void main(String args[]){
??Comparable c = "abc" ;
??System.out.println(c) ;
?}
};
分析:
?1、?所有对象打印的时候调用的都是toString()
?2、?String类中已经覆写toString()
?3、?String是Object的子类。
?4、?如果直接打印Comparable接口对象,调用的是toString()方法,但是此时此对象是通过String实例化的,所以肯定使的是String中已经被覆写toString()方法。
?对于JAVA中可以使用以下的方式规定出二叉树的排序方式:
class BinaryTree{
?class Node{
??// 具体的内容
??private Comparable data ;
??// 保存左子树
??private Node left ;
??// 保存右子树
??private Node right ;
??public void addNode(Node newNode){
???// 要确定是放在左子树还是右子树
???if(newNode.data.compareTo(this.data)<0){
????// 放在左子树
????if(this.left==null){
?????this.left = newNode ;
????}else{
?????this.left.addNode(newNode) ;
????}
???}
???if(newNode.data.compareTo(this.data)>0){
????// 放在左子树
????if(this.right==null){
?????this.right = newNode ;
????}else{
?????this.right.addNode(newNode) ;
????}
???}
??}
??public void printNode(){
???// 先输出左子树
???if(this.left!=null){
????this.left.printNode() ;
???}
???// 输出根节点
???System.out.println(this.data) ;
???// 输出右子树
???if(this.right!=null){
????this.right.printNode() ;
???}
??}
?};
?// 确定根元素
?private Node root ;
?public void add(Comparable data){
??Node newNode = new Node() ;
??newNode.data = data ;
??if(root==null){
???// 第一个元素,设置成根元素
???root = newNode ;
??}else{
???// 如果此语句没有执行的话,则必须确定好是放在左子树还是右子树
???root.addNode(newNode) ;
??}
?}
?public void print(){
??this.root.printNode() ;
?}
};
public class ColDemo23{
?public static void main(String args[]){
??BinaryTree bt = new BinaryTree() ;
??bt.add("C") ;
??bt.add("X") ;
??bt.add("A") ;
??bt.add("S") ;
??bt.add("O") ;
??bt.print() ;
?}
};
3.4、Iterator接口
3.4.1、接口的主要用处
?Iterator是一个迭代输出接口。
?Iterator接口定义:
??? 判断下一个元素是否有内容:public boolean hasNext()
??? 取出内容:public Object next() ;
??? 从集合中删除元素:public void remove() ;
例如:使用Iterator输出Collection(List)中的内容
import java.util.* ;
public class ColDemo07{
?public static void main(String args[]){
??// Collection all = new ArrayList() ;
??List all = new ArrayList() ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??Iterator iter = all.iterator() ;
??while(iter.hasNext()){
???String str = (String)iter.next() ;
???System.out.println(str) ;
??}
?}
};
3.4.2、删除元素的说明
?在List和Iterator上都有remove方法。
?在使用Iterator迭代输出的时候,不能修改List中的内容,如果一旦修改,则肯定会出现错误。
例如:以下代码在迭代输出的时候使用了List中的remove方法。
import java.util.* ;
public class ColDemo08{
?public static void main(String args[]){
??// Collection all = new ArrayList() ;
??List all = new ArrayList() ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??Iterator iter = all.iterator() ;
??while(iter.hasNext()){
???String str = (String)iter.next() ;
???if("C".equals(str)){
????// 使用了List中的删除语法。
????all.remove(str) ;
???}
??}
?}
};
?以上代码运行时出现了错误:
Exception in thread "main" java.util.ConcurrentModificationException
??????? at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
??????? at java.util.AbstractList$Itr.next(Unknown Source)
??????? at ColDemo08.main(ColDemo08.java:11)
?同样的代码,现在直接使用Iterator中的删除方法完成:
import java.util.* ;
public class ColDemo09{
?public static void main(String args[]){
??// Collection all = new ArrayList() ;
??List all = new ArrayList() ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??Iterator iter = all.iterator() ;
??while(iter.hasNext()){
???String str = (String)iter.next() ;
???if("C".equals(str)){
????// 使用了Iterator中的删除语法。
????iter.remove() ;
???}
??}
??System.out.println(all) ;
?}
};
3.4.3、子接口 —— ListIterator
?Iterator本身只支持由前向后的输出,并不支持由后向前,那么其有一个子接口 —— ListIterator,此接口可以将内容从前向后,也可以从后向前,但是必须注意的是:必须先由前向后输出完之后,才能由后向前输出。只有List接口的对象才可以使用此种方法。
?ListIterator中的主要方法:
??? 判断是否有下一个内容:public boolean hasNext()
??? 取出下一个元素:public Object next()
??? 判断是否有上一个元素:public boolean hasPrevious();
??? 取出上一个元素:public Object previous() ;
??? 本身ListIterator也是支持泛型的
例如:以下代码演示了ListIterator的作用
import java.util.* ;
public class ColDemo13{
?public static void main(String args[]){
??List<String> all = new ArrayList<String>() ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??all.add("D") ;
??all.add("E") ;
??ListIterator<String> liter = all.listIterator() ;
??System.out.println(" ============== 由前向后输出 ==================") ;
??while(liter.hasNext()){
???System.out.print(liter.next()+"、") ;
??}
??System.out.println("") ;
??System.out.println(" ============== 由后向前输出 ==================") ;
??while(liter.hasPrevious()){
???System.out.print(liter.previous()+"、") ;
??}
?}
};
3.4、Enumeration接口
?是最早的迭代输出接口,其本身的功能和Iterator类似,但是因为其出现较早,而且代码本身存在安全问题,所以现在使用较少,但是对于一些原有的系统中的若干方法,还是只能使用Enumeration输出。
?Enumerationi接口的定义:
??? 判断是否有下一个元素:public boolean hasMoreElements()
??? 取出元素:public Object nextElement()
例如:使用Enumeration输出Vector中的内容
import java.util.* ;
public class ColDemo15{
?public static void main(String args[]){
??Vector<String> all = new Vector<String>() ;
??all.add("A") ;
??all.add("B") ;
??all.add("C") ;
??all.add("D") ;
??all.add("E") ;
??Enumeration<String> enu = all.elements() ;
??while(enu.hasMoreElements()){
???System.out.print(enu.nextElement()+"、") ;
??}
?}
};
3.5、foreach输出(了解)
?提供了比Iterator更简单的输出语法,但是是在JDK 1.5之后才增加的。
语法格式:
for(类型 对象:集合){
?进行对象的操作
}
例如:验证foreach语法
import java.util.* ;
class Person implements Comparable<Person>{
?private String name ;
?private int age ;
?public Person(String name,int age){
??this.name = name ;
??this.age = age ;
?}
?public String toString(){
??return "姓名;" + this.name + ",年龄;" + this.age ;
?}
?public int compareTo(Person per){
??if(this.age>per.age){
???return -1 ;
??}else if(this.age<per.age){
???return 1 ;
??}else{
???return 0 ;
??}
?}
};
public class ColDemo21{
?public static void main(String args[]){
??Set<Person> all = new TreeSet<Person>() ;
??all.add(new Person("张三",30)) ;
??all.add(new Person("李四",31)) ;
??all.add(new Person("王五",32)) ;
??for(Person p:all){
???System.out.println(p) ;
??}
?}
};
3.6、Map接口
?与之前Collection不同的是Map接口可以存放一对值。
?Map与Set一样,本身不能有任何重复的内容(key不能重复)。
?主要操作方法如下;
??? 向集合中插入一组数据:public V put(K key,V value)
??? 根据key取出value:public V get(Object key)
?在Map中因为其组成较为特殊,所以本身不直接支持Iterator输出。
Set实例? entrySet() ???? 步骤:Map 区分key和value。? Map.Entry实例 ? Iterator ?
??? Map.Entry:是Map的内部接口
???|- 得到key:public K getKey()
|- 得到value:public V getValue()
??? 操作方法:
???|- 将全部的Map变为Set集合:public Set<Map.Entry<K,V>> entrySet()
???|- 将全部的key变为Set集合:public Set<K> keySet()
???|- 将全部的value变为Collection集合:public Collection<V> values()
3.6.1、常用子类
?1、?HashMap:是一个新的类,是在JDK 1.2之后推出的,属于异步处理方式。
?2、?Hashtable:是一个旧的类,是在JDK 1.0时推出,属于同步处理方式
?3、?TreeMap:按照key排序,同样key所在的类必须实现Comparable接口
3.6.2、Hashtable子类 —— Properties
?与Hashtable不同的是Properties主要操作的内容为字符串,表示的是属性操作。
?Properties的主要方法:
??? 设置属性:public Object setProperty(String key, String value)
??? 取得属性:
???|- public String getProperty(String key):根据key找到value,没找到返回null。
|- public String getProperty(String key,String defaultValue):如果没有找到,则指定默认值。
??? 保存属性到文件:public void store(OutputStream out,String comments) throws IOException
??? 从文件中读取内容:public void load(InputStream inStream) throws IOException
??? 把文件保存成XML样式:
???|- public void storeToXML(OutputStream os,String comment) throws IOException
??? 从XML样式的文件之中读取属性:
???|- public void loadFromXML(InputStream in) throws IOException,
??????????????????????? InvalidPropertiesFormatException
3.6.3、Map操作(HashMap)
例如:通过HashMap验证Map的使用
import java.util.* ;
public class ColDemo24{
?public static void main(String arg[]){
??Map<String,String> m = new HashMap<String,String>() ;
??m.put("zhangsan","123456") ;
??m.put("lisi","234567") ;
??m.put("wangwu","345678") ;
??String str = m.get("zhangsan") ;
??System.out.println(str) ;
??System.out.println(m.get("xxx")) ;
?}
};
3.6.4、Map操作(Hashtable)
import java.util.* ;
public class ColDemo25{
?public static void main(String arg[]){
??Map<String,String> m = new Hashtable<String,String>() ;
??m.put("zhangsan","123456") ;
??m.put("lisi","234567") ;
??m.put("wangwu","345678") ;
??String str = m.get("zhangsan") ;
??System.out.println(str) ;
??System.out.println(m.get("xxx")) ;
?}
};
3.6.5、Map操作(TreeMap)
import java.util.* ;
public class ColDemo26{
?public static void main(String arg[]){
??Map<String,String> m = new TreeMap<String,String>() ;
??m.put("zhangsan","123456") ;
??m.put("lisi","234567") ;
??m.put("wangwu","345678") ;
??String str = m.get("zhangsan") ;
??System.out.println(str) ;
??System.out.println(m.get("xxx")) ;
?}
};
3.6.6、Map操作(输出)
1、?使用Iterator输出Map中的全部数据(格式是固定的)
?? public Set<Map.Entry<K,V>> entrySet()
import java.util.* ;
public class ColDemo27{
?public static void main(String arg[]){
??Map<String,String> m = new TreeMap<String,String>() ;
??m.put("zhangsan","123456") ;
??m.put("lisi","234567") ;
??m.put("wangwu","345678") ;
??Set<Map.Entry<String,String>> all = m.entrySet() ;
??Iterator<Map.Entry<String,String>> iter = all.iterator() ;
??while(iter.hasNext()){
???Map.Entry me = iter.next() ;
???System.out.println(me.getKey() + " --> " + me.getValue()) ;
??}
?}
};
2、?将Map中全部的key输出
import java.util.* ;
public class ColDemo28{
?public static void main(String arg[]){
??Map<String,String> m = new TreeMap<String,String>() ;
??m.put("zhangsan","123456") ;
??m.put("lisi","234567") ;
??m.put("wangwu","345678") ;
??Set<String> all = m.keySet() ;
??Iterator<String> iter = all.iterator() ;
??while(iter.hasNext()){
???System.out.println(iter.next()) ;
??}
?}
};
3、?将Map中全部的value输出
import java.util.* ;
public class ColDemo29{
?public static void main(String arg[]){
??Map<String,String> m = new TreeMap<String,String>() ;
??m.put("zhangsan","123456") ;
??m.put("lisi","234567") ;
??m.put("wangwu","345678") ;
??Collection<String> all = m.values() ;
??Iterator<String> iter = all.iterator() ;
??while(iter.hasNext()){
???System.out.println(iter.next()) ;
??}
?}
};
3.6.7、Map操作(问题)
例如:定义一个Person类,里面有name和age属性,之后在Map中保存一个person对象。
import java.util.* ;
class Person{
?private String name ;
?private int age ;
?public Person(String name,int age){
??this.name = name ;
??this.age = age ;
?}
?public String toString(){
??return "姓名:" + this.name + ",年龄:" + this.age ;
?}
};
public class ColDemo30{
?public static void main(String args[]){
??Map<String,Person> m = new HashMap<String,Person>() ;
??m.put("zhangsan",new Person("张三",30)) ;
??System.out.println(m.get("zhangsan")) ;
?}
};
?以上的运行结果,可以发现内容已经查找出来了。如果现在换个方式,使用Person对象表示张三呢?
import java.util.* ;
class Person{
?private String name ;
?private int age ;
?public Person(String name,int age){
??this.name = name ;
??this.age = age ;
?}
?public String toString(){
??return "姓名:" + this.name + ",年龄:" + this.age ;
?}
};
public class ColDemo31{
?public static void main(String args[]){
??Map<Person,String> m = new HashMap<Person,String>() ;
??m.put(new Person("张三",30),"zhangsan") ;
??System.out.println(m.get(new Person("张三",30))) ;
?}
};
?从运行结果,发现,里面没有任何的内容,返回一个“null”。此时再修改代码:
import java.util.* ;
class Person{
?private String name ;
?private int age ;
?public Person(String name,int age){
??this.name = name ;
??this.age = age ;
?}
?public String toString(){
??return "姓名:" + this.name + ",年龄:" + this.age ;
?}
};
public class ColDemo32{
?public static void main(String args[]){
??Map<Person,String> m = new HashMap<Person,String>() ;
??Person p = new Person("张三",30) ;
??m.put(p,"zhangsan") ;
??System.out.println(m.get(p)) ;
?}
};
?以上可以找到代号。
?从以上代码中可以发现问题:
??? 如果使用字符串作为key,就算是匿名对象也是可以找得到
??? 如果自己编写了一个key,则如果使用匿名对象则无法找到。
?因为在对象上有一个对象自己的编码,那么如果要想使用此编码,则必须在对象所在的类中覆写Object类中的hashCode()方法。
import java.util.* ;
class Person{
?private String name ;
?private int age ;
?public Person(String name,int age){
??this.name = name ;
??this.age = age ;
?}
?public String toString(){
??return "姓名:" + this.name + ",年龄:" + this.age ;
?}
?public boolean equals(Object obj){
??if(this==obj){
???return true ;
??}
??if(!(obj instanceof Person)){
???return false ;
??}
??Person p = (Person)obj ;
??if(this.name.equals(p.name)&&this.age==p.age){
???return true ;
??}else{
???return false ;
??}
?}
?public int hashCode(){
??// 正常来说,应该为hashCode的产生自己定义一个公式
??return this.age * this.name.hashCode() ;
?}
};
public class ColDemo33{
?public static void main(String args[]){
??Map<Person,String> m = new HashMap<Person,String>() ;
??m.put(new Person("张三",30),"zhangsan") ;
??System.out.println(m.get(new Person("张三",30))) ;
?}
};
3.6.8、Properties操作
1、?向Properties中设置属性,并取得属性
import java.util.* ;
public class ColDemo35{
?public static void main(String args[]){
??Properties pro = new Properties() ;
??pro.setProperty("BJ","BeiJing") ;
??pro.setProperty("NJ","NanJing") ;
??pro.setProperty("SH","ShangHai") ;
??System.out.println(pro.getProperty("BJ")) ;
??System.out.println(pro.getProperty("XJ")) ;
??System.out.println(pro.getProperty("XJ","nofound")) ;
?}
};
2、?将全部的属性保存在普通文件之中
import java.util.* ;
import java.io.* ;
public class ColDemo36{
?public static void main(String args[]) throws Exception{
??Properties pro = new Properties() ;
??pro.setProperty("BJ","BeiJing") ;
??pro.setProperty("NJ","NanJing") ;
??pro.setProperty("SH","ShangHai") ;
??pro.store(new FileOutputStream(new File("e:\\pro.ini")),"AREA") ;
?}
};
3、?从文件中读取属性
import java.util.* ;
import java.io.* ;
public class ColDemo37{
?public static void main(String args[]) throws Exception{
??Properties pro = new Properties() ;
??pro.load(new FileInputStream(new File("e:\\pro.ini"))) ;
??System.out.println(pro.getProperty("BJ")) ;
?}
};
4、?将属性按照XML样式的风格进行保存
import java.util.* ;
import java.io.* ;
public class ColDemo38{
?public static void main(String args[]) throws Exception{
??Properties pro = new Properties() ;
??pro.setProperty("BJ","BeiJing") ;
??pro.setProperty("NJ","NanJing") ;
??pro.setProperty("SH","ShangHai") ;
??pro.storeToXML(new FileOutputStream(new File("e:\\pro.xml")),"AREA") ;
?}
};
5、?将属性从XML中读取出来
import java.util.* ;
import java.io.* ;
public class ColDemo39{
?public static void main(String args[]) throws Exception{
??Properties pro = new Properties() ;
??pro.loadFromXML(new FileInputStream(new File("e:\\pro.xml"))) ;
??System.out.println(pro.getProperty("BJ")) ;
?}
};
?现在操作属性的时候基本上都是以XML样式为准。
3.7、实例
3.7.1、实例一
?一个人有多本书,一本书属于一个人。
package org.lxh.demo1;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
class Person {
?private String name;
?private int age;
?private List<Book> allBooks;
?public Person() {
??this.allBooks = new ArrayList<Book>();
?}
?public Person(String name, int age) {
??this();
??this.name = name;
??this.age = age;
?}
?public String getName() {
??return name;
?}
?public void setName(String name) {
??this.name = name;
?}
?public int getAge() {
??return age;
?}
?public void setAge(int age) {
??this.age = age;
?}
?public List<Book> getAllBooks() {
??return allBooks;
?}
?public void setAllBooks(List<Book> allBooks) {
??this.allBooks = allBooks;
?}
}
class Book {
?private String title;
?private Person person;
?public Book(String title) {
??super();
??this.title = title;
?}
?public String getTitle() {
??return title;
?}
?public void setTitle(String title) {
??this.title = title;
?}
?public Person getPerson() {
??return person;
?}
?public void setPerson(Person person) {
??this.person = person;
?}
}
public class Demo01 {
?public static void main(String[] args) {
??Person per = new Person("张三", 30);
??Book b1 = new Book("JAVA");
??Book b2 = new Book("C");
??Book b3 = new Book("NET");
??per.getAllBooks().add(b1);
??per.getAllBooks().add(b2);
??per.getAllBooks().add(b3);
??b1.setPerson(per);
??b2.setPerson(per);
??b3.setPerson(per);
??System.out.println("姓名:" + per.getName() + ",年龄:" + per.getAge());
??Iterator<Book> iter = per.getAllBooks().iterator();
??while (iter.hasNext()) {
???System.out.println("\t|- " + iter.next().getTitle());
??}
?}
}
3.7.2、实例二
?一个学生可以选多个课程,一个课程可以多个学生参加。
package org.lxh.demo2;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
class Student {
?private String name;
?private List<Course> allCourses;
?public Student() {
??this.allCourses = new ArrayList<Course>();
?}
?public Student(String name) {
??this();
??this.name = name;
?}
?public String getName() {
??return name;
?}
?public void setName(String name) {
??this.name = name;
?}
?public List<Course> getAllCourses() {
??return allCourses;
?}
?public void setAllCourses(List<Course> allCourses) {
??this.allCourses = allCourses;
?}
}
class Course {
?private String name;
?public List<Student> allStudents;
?public Course() {
??this.allStudents = new ArrayList<Student>();
?}
?public Course(String name) {
??this();
??this.name = name;
?}
?public String getName() {
??return name;
?}
?public void setName(String name) {
??this.name = name;
?}
?public List<Student> getAllStudents() {
??return allStudents;
?}
?public void setAllStudents(List<Student> allStudents) {
??this.allStudents = allStudents;
?}
}
public class Demo02 {
?public static void main(String[] args) {
??Student s1 = new Student("张三");
??Student s2 = new Student("李四");
??Student s3 = new Student("王五");
??Student s4 = new Student("赵六");
??Student s5 = new Student("孙七");
??Course c1 = new Course("JAVA");
??Course c2 = new Course("Oracle");
??// 设置关系
??s1.getAllCourses().add(c1);
??c1.getAllStudents().add(s1);
??s2.getAllCourses().add(c1);
??c1.getAllStudents().add(s2);
??s3.getAllCourses().add(c1);
??c1.getAllStudents().add(s3);
??s4.getAllCourses().add(c2);
??c2.getAllStudents().add(s4);
??s5.getAllCourses().add(c2);
??c2.getAllStudents().add(s5);
??s1.getAllCourses().add(c2);
??c2.getAllStudents().add(s1);
??s2.getAllCourses().add(c2);
??c2.getAllStudents().add(s2);
??System.out.println("学生:" + s1.getName());
??Iterator<Course> iter1 = s1.getAllCourses().iterator();
??while (iter1.hasNext()) {
???System.out.println("\t|- " + iter1.next().getName());
??}
??System.out.println("---------------------------------");
??System.out.println("课程:" + c2.getName());
??Iterator<Student> iter2 = c2.getAllStudents().iterator();
??while (iter2.hasNext()) {
???System.out.println("\t|- " + iter2.next().getName());
??}
?}
}
4、总结
1、?Collection(保存单个对象)
?? List:允许有重复元素,拥有更多的操作方法
??|- ArrayList:新的、异步处理
??|- Vector:旧的, 同步处理,支持Iterator和Enumeration两种输出
???|- Stack:入栈、出栈
?? Set:不允许有重复元素,靠hashCode和equals方法来区分重复元素
??|- HashSet:无序
??|- TreeSet:有序、按照Comparable指定的规则排序
?? 常用方法:add()、iterator()、remove
2、?Map(保存一对对象)
?? HashMap:新的类,异步处理
?? Hashtable:旧的类,同步处理
??|- Properties(属性操作),可以将属性保存在文件之中
?? TreeMap:排序操作类,此类按key排序,使用Comparable完成
?? 主要方法:put、get、entrySet
?? Map不能直接使用Iterator输出,必须转换成Set,通过Map.Entry分离key和value
3、?Iterator
?? 输出接口,只要是类集都使用此接口输出,一般情况下很少有删除代码出现
?? 主要方法:
??|- 判断是否有下一个元素:public boolean hasNext()
??|- 取出当前元素:public Object next()
?? 子接口:ListIterator
??|- 双向输出,但是此接口只能通过List实例化
4、?Enumeration接口
?? 最早的输出接口,现在部分代码上依然使用