集合概述

当需要在Java程序中记录单个数据内容时,则声明一个变量。

当需要在Java程序中记录多个类型相同的数据内容时,声明一个一维数组。

当需要在Java程序中记录多个类型不同的数据内容时,则创建一个对象。

当需要在Java程序中记录多个类型相同的对象数据时,创建一个对象数组。

当需要在Java程序中记录多个类型不同的对象数据时,则准备一个集合。

集合的框架结构

集合的框架结构 Java中集合框架顶层框架是:java.util.Collection集合 和 java.util.Map集合。

其中Collection集合中存取元素的基本单位是:单个元素。

其中Map集合中存取元素的基本单位是:单对元素。

Collection集合

java.util.Collection接口是List接口、Queue 接口以及Set接口的父接口,因此该接口里定义的方法 既可用于操作List集合,也可用于操作Queue集合和Set集合。

常用的方法

方法如下:

  • public boolean add(E e): 把给定的对象添加到当前集合中 。

  • public void clear() :清空集合中所有的元素。

  • public boolean remove(E e): 把给定的对象在当前集合中删除。

  • public boolean contains(E e): 判断当前集合中是否包含给定的对象。

  • public boolean isEmpty(): 判断当前集合是否为空。

  • public int size(): 返回集合中元素的个数。

  • public Object[] toArray(): 把集合中的元素,存储到数组中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public static void main(String[] args) {
//创建集合对象
//使用多态形式
Collection<String> coll = new ArrayList<String>();
//使用方法
//添加功能boolean add(String s)
coll.add("小李广");
coll.add("扫地僧");
coll.add("石破天");
System.out.println(coll);
//boolean contains(E e) 判断o是否在集合中存在
System.out.println("判断 扫地僧 是否在集合中"+coll.contains("扫地僧"));
//boolean remove(E e) 删除在集合中的o元素
System.out.println("删除石破天:"+coll.remove("石破天"));
System.out.println("操作之后集合中元素:"+coll);
//size() 集合中有几个元素
System.out.println("集合中有"+coll.size()+"个元素");
//Object[] toArray()转换成一个Object数组
Object[] objects = coll.toArray();
//遍历数组
for (int i = 0; i < objects.length; i++) {
System.out.println(objects[i]);
}
//void clear() 清空集合
coll.clear();
System.out.println("集合中内容为:"+coll);
//boolean isEmpty() 判断是否为空
System.out.println(coll.isEmpty());

}

Iterator接口

java.util.Iterator接口主要用于描述迭代器对象,可以遍历Collection集合中的所有元素。 java.util.Collection接口继承Iterator接口,因此所有实现Collection接口的实现类都可以使用该迭代器对象。

方法声明 功能介绍
boolean hasNext() 判断集合中是否有可以迭代/访问的元素
E next() 用于取出一个元素并指向下一个元素
void remove() 用于删除访问到的最后一个元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public static void main(String[] args) {
//1.准备一个Collection集合并放入元素后打印
Collection c1 = new ArrayList();
c1.add("one");
c1.add(2);
c1.add(new Person("zhangfei", 30));//遍历方式一:自动调用toString方法 String类型的整体
System.out.println("c1 = " + c1);
//[one, 2, Person{name='zhangfei', age=30}]
System.out.println("-----------------------------");
//2.遍历方式二:使用迭代器来遍历集合中的所有元素 更加灵活
//2.1获取当前集合中的迭代器对象
Iterator iterator1 = c1.iterator();//2.2判断是否有元素可以访问
System.out.println(iterator1.hasNext()); //true//2.3取出一个元素并指向下一个
System.out.println("获取到的元素是:" + iterator1.next());//one
System.out.println(iterator1.hasNext());//true
System.out.println("获取到的元素是:" + iterator1.next());//2
System.out.println(iterator1.hasNext());//true
System.out.println("获取到的元素是:" + iterator1.next());
//Person{name='zhangfei', age=30}
System.out.println(iterator1.hasNext());//false
//编译ok,运行发生NoSuchElementException没有这样的元素异常
System.out.println("获取到的元素是:" + iterator1.next());
while(iterator1.hasNext()){
System.out.println("获取到的元素是:" + iterator1.next());
}
}

遍历集合

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
Collection<String> coll = new ArrayList<String>();
coll.add("hd");
coll.add("jc");
coll.add("wyb");
//使用增强for遍历
for(String s :coll){
//接收变量s代表 代表被遍历到的集合元素
System.out.println(s);
}
}

List集合

基本概念

java.util.List集合是Collection集合的子集合,该集合中允许有重复的元素并且有先后放入次序。

该集合的主要实现类有:ArrayList类、LinkedList类、Stack类、Vector类。

其中ArrayList类的底层是采用动态数组进行数据管理的,支持下标访问,增删元素不方便。

其中LinkedList类的底层是采用双向链表进行数据管理的,访问不方便,增删元素方便。

ArrayList 更适合于随 机访问而LinkedList更适合于插入和删除;在性能要求不是特别苛刻的情形下可以忽略这个差别。

其中Stack类的底层是采用动态数组进行数据管理的,该类主要用于描述一种具有后进先出特征的 数据结构,叫做栈(last in first out LIFO)。

其中Vector类的底层是采用动态数组进行数据管理的,该类与ArrayList类相比属于线程安全的 类,效率比较低,以后开发中基本不用。

常用方法

List作为Collection集合的子接口,不但继承了Collection接口中的全部方法,而且还增加了一些根据元素索引来操作集合的特有方法,如下:

  • public void add(int index, E element): 将指定的元素,添加到该集合中的指定位置上。

  • public E get(int index):返回集合中指定位置的元素。

  • public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。

  • public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前的元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public static void main(String[] args){
//创建List集合对象
List<String> list = new ArrayList<String>();
//往尾部添加指定元素
list.add("图图");
list.add("小美");
list.add("不高兴");
System.out.println(list);
//add(int index,String s)往指定位置添加
list.add(1,"没头脑");
System.out.println(list);
//String remove(int index) 删除指定位置元素返回被删除元素
//删除索引位置为2的元素
System.out.println("删除索引位置为2的元素");
System.out.println(list.remove(2));
System.out.println(list);
//String set(int index,String s)在指定位置进行元素替代(改)
//修改指定位置元素
list.set(0, "三毛");
System.out.println(list);
//String get(int index)获取指定位置元素
//跟size()方法一起用来遍历的
for(int i = 0;i<list.size();i++){
System.out.println(list.get(i));
}
//还可以使用增强for
for (String string : list) {
System.out.println(string);
}
}

List的子类

ArrayList集合

java.util.ArrayList集合数据存储的结构是数组结构。元素增删慢查找快,由于日常开发中使用最多的功能为查询数据、遍历数据,所以ArrayList是最常用的集合。

LinkedList集合

java.util.LinkedList集合数据存储的结构是链表结构。方便元素添加、删除的集合。

常用方法

  • public void addFirst(E e):将指定元素插入此列表的开头。

  • public void addLast(E e):将指定元素添加到此列表的结尾。

  • public E getFirst():返回此列表的第一个元素。

  • public E getLast():返回此列表的最后一个元素。

  • public E removeFirst():移除并返回此列表的第一个元素。

  • public E removeLast():移除并返回此列表的最后一个元素。

  • public E pop():从此列表所表示的堆栈处弹出一个元素。

  • public void push(E e):将元素推入此列表所表示的堆栈。

  • public boolean isEmpty():如果列表不包含元素,则返回true。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void main(String[] args) {
LinkedList<String> link = new LinkedList<String>();
//添加元素
link.addFirst("abc1");
link.addFirst("abc2");
link.addFirst("abc3");
System.out.println(link);
//获取元素
System.out.println(link.getFirst());
System.out.println(link.getLast());
//删除元素
System.out.println(link.removeFirst());
System.out.println(link.removeLast());
while (!link.isEmpty()) {
//判断集合是否为空
System.out.println(link.pop());
//弹出集合中的栈顶元素
}
System.out.println(link);
}

Set接口

java.util.Set接口和java.util.List接口一样,同样继承自Collection接口,它与Collection接口中的方法基本一致,并没有对Collection接口进行功能上的扩充,只是比Collection接口更加严格了。与List接口不同的是,Set接口中元素无序,并且都会以某种规则保证存入的元素不出现重复

Set集合有多个子类,这里我们介绍其中的java.util.HashSetjava.util.LinkedHashSet这两个集合。

HashSet集合

  • 底层数据结构是哈希表

  • 存取无序

  • 不可以存储重复元素

  • 没有索引,不能使用普通for循环遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) throws Exception {
Student stu1=new Student("令狐冲",19);
Student stu2=new Student("令狐冲",19);
Student stu3=new Student("风清扬",79);
Student stu4=new Student("岳不群",49);
HashSet<Student> set=new HashSet<Student>();
set.add(stu1);
set.add(stu2);
set.add(stu3);
set.add(stu4);
System.out.println(set.contains(stu2));
for(Student stu:set){
System.out.println(stu);
}
}

覆盖Student中的equals和hashCode方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
public boolean equals(Object obj){
if(obj instanceof  Student){
Student stu= (Student) obj;
if(stu.age==this.age&&stu.name.equals(this.name)){
return true;
}
}
return false;
}
@Override
public int hashCode(){
return name.hashCode()+age;
}

for循环遍历后删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static void main(String[] args) {
Student stu1=new Student("吴作成",18);
Student stu2=new Student("杨志超",19);
Student stu3=new Student("商政",21);
Student stu4=new Student("商政",21);
Student stu5=new Student("靳东升",20);
HashSet<Student> set=new HashSet<Student>();
set.add(stu1);
set.add(stu2);
set.add(stu3);
set.add(stu4);
set.add(stu5);
System.out.println(set);
HashSet<Student> setDel=new HashSet<Student>();
for(Student stu:set){
if(stu.name.startsWith("商")){
setDel.add(stu);
}
}
set.removeAll(setDel);
System.out.println(set);
}

LinkedHashSet

我们知道HashSet保证元素唯一,可是元素存放进去是没有顺序的,那么我们要保证有序,怎么办呢?

在HashSet下面有一个子类java.util.LinkedHashSet,它是链表和哈希表组合的一个数据存储结构。

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
Set<String> set = new LinkedHashSet<String>();
set.add("bbb");
set.add("aaa");
set.add("abc");
set.add("bbc");
Iterator<String> it = set.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}

TreeSet集合

TreeSet集合概述和特点【应用】

  • 不可以存储重复元素

  • 没有索引

  • 红黑树 TreeSet

  • 可以将元素按照规则进行排序

  • TreeSet():根据其元素的自然排序进行排序

  • TreeSet(Comparator comparator) :根据指定的比较器进行排序

TreeSet集合基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//1.准备一个TreeSet集合并打印
Set<String> s1 = new TreeSet<>();
System.out.println("s1 = " + s1);
//[啥也没有]//2.向集合中添加String类型的对象并打印
boolean b1 = s1.add("aa");
System.out.println("b1 = " + b1);//true
System.out.println("s1 = " + s1);//[aa]
b1 = s1.add("cc");
System.out.println("b1 = " + b1);//true
System.out.println("s1 = " + s1);//[aa, cc]
b1 = s1.add("bb");
System.out.println("b1 = " + b1);//true
//由于TreeSet集合的底层是采用红黑树实现的,因此元素有大小次序,默认从小到大打印
System.out.println("s1 = " + s1);//[aa, bb, cc]

排序Comparator和Comparable接口

实现Comparable 接口 并重写方法

1
2
3
4
5
6
7
8
public class Student implements Comparable<Student>{
@Override
public int compareTo(Student stu) {
if(this.age>stu.age) return -1;
if(this.age<stu.age) return 1;
return 0;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) throws Exception {
Student stu1=new Student("令狐冲",19);
Student stu2=new Student("令狐冲",19);
Student stu3=new Student("风清扬",79);
Student stu4=new Student("岳不群",49);
TreeSet<Student> set= new TreeSet<Student>();
set.add(stu1);
set.add(stu2);
set.add(stu3);
set.add(stu4);
System.out.println(set.contains(stu2));
for(Student stu:set){
System.out.println(stu);
}
}

实现Comparator接口的比较器

1
2
3
4
5
6
7
8
public class StuComptor implements Comparator<Student> {
@Override
public int compare(Student stu1, Student stu2) {
if(stu1.age>stu2.age)return 1;
if(stu1.age<stu2.age)return -1;
return 0;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) throws Exception {    
Student stu1=new Student("令狐冲",19);
Student stu2=new Student("令狐冲",19);
Student stu3=new Student("风清扬",79);
Student stu4=new Student("岳不群",49);
TreeSet<Student> set= new TreeSet<Student>(new StuComptor());
set.add(stu1);
set.add(stu2);
set.add(stu3);
set.add(stu4);
System.out.println(set.contains(stu2));
for(Student stu:set){
System.out.println(stu);
}
}
  • 两种比较方式小结

    • 自然排序: 自定义类实现Comparable接口,重写compareTo方法,根据返回值进行排序

    • 比较器排序: 创建TreeSet对象的时候传递Comparator的实现类对象,重写compare方法,根据返回值进行排序

    • 在使用的时候,默认使用自然排序,当自然排序不满足现在的需求时,必须使用比较器排序

  • 两种方式中关于返回值的规则

    • 如果返回值为负数,表示当前存入的元素是较小值,存左边
    • 如果返回值为0,表示当前存入的元素跟集合中元素重复了,不存
    • 如果返回值为正数,表示当前存入的元素是较大值,存右边

Collections

  • java.utils.Collections是集合工具类,用来对集合进行操作。部分方法如下:

  • public static <T> boolean addAll(Collection<T> c, T... elements):往集合中添加一些元素。

  • public static void shuffle(List<?> list):打乱集合顺序。

  • public static <T> void sort(List<T> list):将集合中元素按照默认规则排序。

  • public static <T> void sort(List<T> list,Comparator<? super T> ):将集合中元素按照指定规则排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
//原来写法
//list.add(12);
//list.add(14);
//list.add(15);
//list.add(1000);
//采用工具类 完成 往集合中添加元素
Collections.addAll(list, 5, 222, 12);
System.out.println(list);
//排序方法
Collections.sort(list);
System.out.println(list);
}

泛型

泛型的介绍

  • 常情况下集合中可以存放不同类型的对象,是因为将所有对象都看做Object类型放入的,因此 从集合中取出元素时也是Object类型,为了表达该元素真实的数据类型,则需要强制类型转换, 而强制类型转换可能会引发类型转换异常。

  • 为了避免上述错误的发生,从Java5开始增加泛型机制,也就是在集合名称的右侧使用<数据类型> 的方式来明确要求该集合中可以存放的元素类型,若放入其它类型的元素则编译报错。

  • 泛型只在编译时期有效,在运行时期不区分是什么类型。

定义格式:修饰符 class 类名<类型> {}

1
2
3
4
5
class ArrayList<E>{
public boolean add(E e){}
public E get(int index){}
....
}

使用在类上的语法

1
2
3
4
5
6
7
8
9
public class JavaBean<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}

泛型方法

定义格式:修饰符 <类型> 返回值类型 方法名(类型 变量名) {}

public void/Integer test(T t)

带有泛型方法的类

1
2
3
4
5
public class JavaObject {
public <T> void set(T t){
System.out.println(t);
}
}
1
2
3
4
5
public static void main(String[] args) {
JavaObject j = new JavaObject();
j.set("hd");
j.set(88);
}

泛型接口

定义格式: 修饰符 interface 接口名<类型> {}

1
2
3
public interface JavaInterface<T> {
void set(T t);
}
1
2
3
4
5
6
public class JavaObjectImpl1 implements JavaInterface<Integer>{
@Override
public void set(Integer t) {
System.out.println(t);
}
}
1
2
3
4
5
6
public static void main(String[] args) {
JavaObjectImpl<String> obj1= new JavaObjectImpl<String>();
obj1.set("hd");
JavaObjectImpl<Integer> obj2= new JavaObjectImpl<Integer>();
obj2.set(88);
}

类型通配符

当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。

通配符高级使用—-受限泛型

之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置。但是在JAVA的泛型中可以指定一个泛型的上限下限

泛型的上限

  • 格式类型名称 <? extends 类 > 对象名称

  • 意义只能接收该类型及其子类

泛型的下限

  • 格式类型名称 <? super 类 > 对象名称

  • 意义只能接收该类型及其父类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static void main(String[] args) {
Collection<Integer> list1 = new ArrayList<Integer>();
Collection<String> list2 = new ArrayList<String>();
Collection<Number> list3 = new ArrayList<Number>();
Collection<Object> list4 = new ArrayList<Object>();
getElement(list1);
getElement(list2);//报错
getElement(list3);
getElement(list4);//报错
getElement2(list1);//报错
getElement2(list2);//报错
getElement2(list3);
getElement2(list4);
}
// 泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类
public static void getElement1(Collection<? extends Number> coll){}
// 泛型的下限:此时的泛型?,必须是Number类型或者Number类型的父类
public static void getElement2(Collection<? super Number> coll){}

Map集合

Map集合概述

interface Map<K,V> K:键的类型;V:值的类型

  • Map集合的特点

  • 双列集合,一个键对应一个值

  • 键不可以重复,值可以重复

Map集合的基本功能

方法名 说明
V put(K key,V value) 添加元素
V remove(Object key) 根据键删除键值对元素
void clear() 移除所有的键值对元素
boolean containsKey(Object key) 判断集合是否包含指定的键
boolean containsValue(Object value) 判断集合是否包含指定的值
boolean isEmpty() 判断集合是否为空
int size() 集合的长度,也就是集合中键值对的个数

遍历方法

方法名 说明
V get(Object key) 根据键获取值
Set keySet() 获取所有键的集合
Collection values() 获取所有值的集合
Set<Map.Entry<K,V>> entrySet() 获取所有键值对对象的集合
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public static void main(String[] args) {
//1.准备一个Map集合并打印
Map<String, String> m1 = new HashMap<>();
//自动调用toString方法,默认打印格式为:{key1=value1, key2=value2, ...}
System.out.println("m1 = " + m1);//{啥也没有}
//2.向集合中添加元素并打印
String str1 = m1.put("1", "one");
System.out.println("原来的value数值为:" + str1);//null
System.out.println("m1 = " + m1);//{1=one}
str1 = m1.put("2", "two");
System.out.println("原来的value数值为:" + str1);//null
System.out.println("m1 = " + m1);//{1=one, 2=two}
str1 = m1.put("3", "three");
System.out.println("原来的value数值为:" + str1);//null
System.out.println("m1 = " + m1);//{1=one, 2=two, 3=three}
//实现了修改的功能
str1 = m1.put("1", "eleven");
System.out.println("原来的value数值为:" + str1);//one
System.out.println("m1 = " + m1);//{1=eleven, 2=two, 3=three}
System.out.println("----------------");
//3.实现集合中元素的查找操作
boolean b1 = m1.containsKey("11");
System.out.println("b1 = " + b1);//false
b1 = m1.containsKey("1");
System.out.println("b1 = " + b1);//true
b1 = m1.containsValue("one");
System.out.println("b1 = " + b1);//false
b1 = m1.containsValue("eleven");
System.out.println("b1 = " + b1);//true
String str2 = m1.get("5");
System.out.println("str2 = " + str2);//null
str2 = m1.get("3");
System.out.println("str2 = " + str2);//three
System.out.println("-------------------------------------");
//4.实现集合中元素的删除操作
str2 = m1.remove("1");
System.out.println("被删除的value是:" + str2);//eleven
System.out.println("m1 = " + m1);//{2=two, 3=three}
System.out.println("---------------------------------------");
//5.获取Map集合中所有的key并组成Set视图
Set<String> s1 = m1.keySet();
//遍历所有的key
for (String ts : s1) {
System.out.println(ts + "=" + m1.get(ts));
}
System.out.println("-----------------------------------");
//6.获取Map集合中所有的Value并组成Collection视图
Collection<String> co = m1.values();
for (String ts : co) {
System.out.println("ts = " + ts);
}
System.out.println("------------------------------------------");
//7.获取Map集合中所有的键值对并组成Set视图
Set<Map.Entry<String, String>> entries = m1.entrySet();
for (Map.Entry<String, String> me : entries) {
System.out.println(me);
}
}

HashMap集合

HashMap集合概述和特点

  • HashMap底层是哈希表结构的

  • 依赖hashCode方法和equals方法保证键的唯一

  • 如果键要存储的是自定义对象,需要重写hashCode和equals方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void main(String[] args) {
//1.遍历字符串
String str = "abcaba";
//声明一个集合 把所有的字母 都加进去
//字母就是key 次数 int value
HashMap<Character, Integer> map = new HashMap<>();
for (char zimu:str.toCharArray()) {
// 如果 字母 存在,次数+1
if(map.containsKey(zimu)){
// 存在,就把value的值+1
Integer cishu = map.get(zimu);
// map.getOrDefault()
cishu++;
map.put(zimu,cishu);
}else{
//如果不存在,就说明是第1次来,存1次
map.put(zimu,1);
}
}
}

TreeMap集合

  • TreeMap底层是红黑树结构

  • 依赖自然排序或者比较器排序,对键进行排序

  • 如果键存储的是自定义对象,需要实现Comparable接口或者在创建TreeMap对象时候给出比较器排序规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class Student implements Comparable<Student>{
private String name;
private int age;
public Student() {}
public Student(String name, int age) {
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;
}
@Override
public String toString() {
return "Student{"+"name='" + name + '\'' +", age=" + age +'}';
}
@Override
public int compareTo(Student o) {
/*按照年龄进行排序*/
int result = o.getAge() - this.getAge();
/*次要条件,按照姓名排序*/
result = result == 0 ? o.getName().compareTo(this.getName()) : result;
return result;
}s
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Test1 {
public static void main(String[] args) {
TreeMap<Student,String> tm = new TreeMap<>();
Student s1 = new Student("hd",88);
Student s2 = new Student("jc",99);
/*将学生对象添加到TreeMap集合中*/
tm.put(s1,"郑州");
tm.put(s2,"北京");
/*遍历TreeMap集合,打印每个学生的信息*/
Set<Map.Entry<Student, String>> entries = tm.entrySet();
for (Map.Entry<Student, String> entry:entries) {
Student key = entry.getKey();
String value = entry.getValue();
System.out.println("key:" + key + "value:" + value);
}
}
}