点击蓝字|关注我们
五、Java中的集合框架(中)
Map接口
Map提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储的,能够实现根据key快速查找value
Map中的键值对以Entry类型的对象实例形式存在
key值不可重复,value值可以重复,一个key最多只能映射到一个值
Map接口提供了分别返回key值集合、value值集合以及Entry(键值对)集合的方法
Map支持泛型,形式如:Map
HashMap类
HashMap是Map的一个重要实现类,也是最常用的,基于哈希表实现
HashMap中的Entry对象是无序排列
Key值和Value值都可以为null,但是一个HashMap只能有一个key值为null的映射(key值不可重复)
HashMap的数据结构是数组+链表,jdk8及以后版本是数组+链表+红黑树
案例实现
通过Map进行学生信息管理,其中key为学生ID,value为学生对象
通过键盘输入学生信息
对集合中的学生信息进行增删改查操作
MapTest.java
import java.util.HashMap;import java.util.Map;import java.util.Map.Entry;import java.util.Scanner;import java.util.Set;public class MapTest { /** * 用来承装学生类型对象 * @param args */ public Map students; /** * 在构造器中初始化students属性 */ public MapTest() { this.students = new HashMap(); } /** * 测试添加:输入学生ID,判断是否被占用 * 若未被占用,则输入姓名,创建新学生对象 * 并且添加到students中 */ public void testPut() { //创建一个Scanner对象,用来获取输入的学生ID和姓名 Scanner console = new Scanner(System.in); int i=0; while(i<3) { System.out.println("请输入学生ID"); String ID = console.next(); //判断该ID是否被占用 Student st = students.get(ID); if(st == null) { //提示输入学生姓名 System.out.println("请输入学生姓名:"); String name = console.next(); //创建新的学生对象 Student newStudent = new Student(ID,name); //通过调用students的put方法,添加ID-学生映射 students.put(ID,newStudent); System.out.println("成功添加学生:"+students.get(ID).name); i++; }else { System.out.println("该学生ID已被占用"); continue; } } } /** * 测试Map的keySet方法 */ public void testKeySet() { //通过keySet方法,返回Map中的所有key的Set集合 Set keySet = students.keySet(); //取得students的容量 System.out.println("总共有"+students.size()+"个学生"); //遍历keySet,取得每一个key,再调用get方法取得每个key对应的value值 for (String stuId : keySet) { Student st = students.get(stuId); if(st != null) { System.out.println("学生:"+st.name); } } } /** * 测试删除Map中的映射 */ public void testRemove() { //获取从键盘输入的学生ID Scanner console = new Scanner(System.in); while(true) { //提示输入待删除的学生ID System.out.println("请输入要删除的学生ID"); String ID = console.next(); //判断该ID是否有对应的学生对象 Student st = students.get(ID); if(st == null) { //提示输入的ID并不存在 System.out.println("该ID不存在"); continue; }else { students.remove(ID); System.out.println("成功删除学生:"+st.name); break; } } } /** * 通过entrySet方法来遍历Map */ public void testEntrySet() { //通过entrySet方法,返回Map中的所有键值对 Set> entrySet = students.entrySet(); for (Entry entry : entrySet) { System.out.println("取得键:"+entry.getKey()); System.out.println("对应的值为:"+entry.getValue().name); } } /** *利用put方法修改Map中的已有映射 */ public void testModify() { //提示输入要修改的学生ID System.out.println("请输入要修改的学生ID"); Scanner console = new Scanner(System.in); while(true) { String stuID = console.next(); //从students中查找该学生ID对应的学生,没有的话要重新输入 Student student = students.get(stuID); if(student == null) { System.out.println("该ID不存在"); continue; }else { System.out.println("当前该学生ID,所对应的的学生为"+student.name); //提示输入新的学生姓名,来修改已有的映射 System.out.println("请输入新的学生姓名"); String name = console.next(); Student newStudent = new Student(stuID,name); students.put(stuID, newStudent); System.out.println("修改成功!"); break; } } } /** * * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub MapTest mt = new MapTest(); mt.testPut(); mt.testKeySet();// mt.testRemove();// mt.testEntrySet(); mt.testModify(); mt.testEntrySet(); }}
六、Java中的集合框架(下)
判断List中课程是否存在
Course.java
在此重写equals方法,达到仅通过name(无需ID)就可以判断该对象是否在List中存在
/** * 课程类 * @author Wang Jiaxin * */public class Course { public String id; public String name; public Course(String id,String name) { this.id = id; this.name = name; } public Course() {}//为了不让子类报错 //实际开发过程,应该将属性私有化,通过使用getter和setter来获取属性// private String id;// public String getId() {// return id;// } public void setId(String id) {// this.id = id;// } @Override public boolean equals(Object obj) { if(this == obj) { return true; } if(obj == null) { return false; } if(!(obj instanceof Course)) { return false; } Course course = (Course)obj; if(this.name == null) { if(course.name == null) { return true; }else { return false; } }else { if(this.name.equals(course.name)) {//为什么在此使用equals非== return true; }else { return false; } } } }
Student.java
import java.util.HashSet;import java.util.Set;/** * 学生类 * @author Wang Jiaxin * */public class Student { public String id; public String name; public Set courses; public Student(String id,String name) { this.id = id; this.name = name; this.courses = new HashSet(); }}
TestSet.java
import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.Scanner;public class SetTest { public List coursesToSelect; private Scanner console;//由于很多方法中会用到Scanner,因此创建对象 public Student student; public SetTest() { coursesToSelect = new ArrayList(); console = new Scanner(System.in);//Scanner对象初始化 } public void testAdd() { //创建一个课程对象,并通过调用add(Object element)方法,添加到备选课程中 Course cr1 = new Course("1","数据结构"); coursesToSelect.add(cr1);// Course temp = coursesToSelect.get(0);//存入的时候是object,取出的时候也是object,因此需要强制类型转换 Course temp = (Course) coursesToSelect.get(0);// System.out.println("添加了课程:"+temp.id+":"+temp.name); //创建一个课程对象,并通过调用add(int index,Object element)方法,添加到备选课程中 Course cr2 = new Course("2","C语言"); coursesToSelect.add(0, cr2); Course temp2 = (Course) coursesToSelect.get(0);// System.out.println("添加了课程:"+temp2.id+":"+temp2.name); /** * 当前coursesToSelect的长度为2, * index从0开始,add(int index,Object element)的index可选为0,1,2 * index为0/1,则element放在第0/1位,后边元素的依次往后错一位 * index为2(当前list的容量,即长度),则直接添加在list的尾部 * index取小于0或者大于list长度的值都会报IndexOutOfBoundsException,下标越界 */ //以下方法会抛出数组下标越界异常:// Course cr3 = new Course("3","test");// coursesToSelect.add(2, cr3); // //重复添加课程cr1:// coursesToSelect.add(cr1);// Course temp0 = (Course) coursesToSelect.get(2);// System.out.println("添加了课程:"+temp0.id+":"+temp0.name); //创建一个课程数组,并通过调用addAll(Arrays.asList(course))方法,添加到备选课程中 Course[] course = { new Course("3","离散数学"), new Course("4","汇编语言") }; //使用Arrays.asList()将数组转换为List coursesToSelect.addAll(Arrays.asList(course)); Course temp3 = (Course) coursesToSelect.get(2); Course temp4 = (Course) coursesToSelect.get(3);// System.out.println("添加了两门课程:"+temp3.id+":"+temp3.name+";"// +temp4.id+":"+temp4.name); //创建一个课程数组,并通过调用addAll(int index, Arrays.asList(course))方法,添加到备选课程中 Course[] course2 = { new Course("5","高等数学"), new Course("6","大学英语") }; coursesToSelect.addAll(2, Arrays.asList(course2)); Course temp5 = (Course) coursesToSelect.get(2); Course temp6 = (Course) coursesToSelect.get(3);// System.out.println("添加了两门课程:"+temp5.id+":"+temp5.name+";"// +temp6.id+":"+temp6.name); } /** * 通过for each方法访问元素 * @param args */ public void testForEach() { System.out.println("有如下课程待选(通过for each访问):"); for(Object obj:coursesToSelect) { /** * 当一个元素被存入集合时,它的类型被忽略,集合只把它当做Object, * 当取出来的时候,还是Object类型,要强转换为原来类型 */ Course cr = (Course) obj; System.out.println("课程:"+cr.id+":"+cr.name); } } /** * 测试List的contains方法 */ public void testListContains() { /** * contains(obj)的原理: * 遍历List中的每个元素,然后equals(obj), * 只要有返回为true的,证明包含该对象, * 因此返回true。否则返回false */ //取得备选课程序列的第0个元素 Course course = coursesToSelect.get(0); //打印输出coursesToSelect是否包含course对象 System.out.println("取得课程:"+course.name); System.out.println("备选课程中是否包含课程:"+course.name+","+coursesToSelect.contains(course));//true/重写equals()后true //创建新的课程对象,ID和名称与course相同 Course course2 = new Course(course.id,course.name); System.out.println("取得课程:"+course2.name); System.out.println("备选课程中是否包含课程:"+course2.name+","+coursesToSelect.contains(course2));//false/重写equals()后true //course 和course2虽然ID和名称相同,但是是两个不同的对象,因此返回false //仅通过name判断List中是否包含该课程 //在Course中重写equals方法即可 //重写之后,判断name相同,则对象相同,contains()返回true //从键盘输入课程名称,判断是否包含 System.out.println("请输入课程名称:"); String name = console.next(); //创建course3,使用无参构造器,然后name赋值 Course course3 = new Course(); course3.name = name; System.out.println("取得课程:"+course3.name); System.out.println("备选课程中是否包含课程:"+course3.name+","+coursesToSelect.contains(course3)); //containsAll()判断是否包含多个元素 } /** * * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub SetTest st = new SetTest(); st.testAdd(); st.testForEach(); st.testListContains(); } public void testForEachForSet(Student student) { //打印输出,学生所选的课程 System.out.println("共选择了"+student.courses.size()+"门课程"); for (Course cr : student.courses) { System.out.println("选择了课程:"+cr.id+":"+cr.name); } //循环遍历Set中的元素只能使用foreach和iterator方法,不能像List一样还能使用get方法 //因为Set是无序的,本身并不能够查找指定位置上的元素 }}
判断Set中课程是否存在
Course.java
重写equals()和hashCode(),在eclipse中source--generate equals() and hashCode(),会自动覆盖掉上个例子中手动重写的equals()方法,只选择name,判断名称是否相同即可
/** * 课程类 * @author Wang Jiaxin * */public class Course { public String id; public String name; public Course(String id,String name) { this.id = id; this.name = name; } public Course() {}//为了不让子类报错 //实际开发过程,应该将属性私有化,通过使用getter和setter来获取属性// private String id;// public String getId() {// return id;// } public void setId(String id) {// this.id = id;// } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Course other = (Course) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } }
SetTest.java
import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.Scanner;public class SetTest { public List coursesToSelect; private Scanner console;//由于很多方法中会用到Scanner,因此创建对象 public Student student; public SetTest() { coursesToSelect = new ArrayList(); console = new Scanner(System.in);//Scanner对象初始化 } public void testAdd() { //创建一个课程对象,并通过调用add(Object element)方法,添加到备选课程中 Course cr1 = new Course("1","数据结构"); coursesToSelect.add(cr1);// Course temp = coursesToSelect.get(0);//存入的时候是object,取出的时候也是object,因此需要强制类型转换 Course temp = (Course) coursesToSelect.get(0);// System.out.println("添加了课程:"+temp.id+":"+temp.name); //创建一个课程对象,并通过调用add(int index,Object element)方法,添加到备选课程中 Course cr2 = new Course("2","C语言"); coursesToSelect.add(0, cr2); Course temp2 = (Course) coursesToSelect.get(0);// System.out.println("添加了课程:"+temp2.id+":"+temp2.name); /** * 当前coursesToSelect的长度为2, * index从0开始,add(int index,Object element)的index可选为0,1,2 * index为0/1,则element放在第0/1位,后边元素的依次往后错一位 * index为2(当前list的容量,即长度),则直接添加在list的尾部 * index取小于0或者大于list长度的值都会报IndexOutOfBoundsException,下标越界 */ //以下方法会抛出数组下标越界异常:// Course cr3 = new Course("3","test");// coursesToSelect.add(2, cr3); // //重复添加课程cr1:// coursesToSelect.add(cr1);// Course temp0 = (Course) coursesToSelect.get(2);// System.out.println("添加了课程:"+temp0.id+":"+temp0.name); //创建一个课程数组,并通过调用addAll(Arrays.asList(course))方法,添加到备选课程中 Course[] course = { new Course("3","离散数学"), new Course("4","汇编语言") }; //使用Arrays.asList()将数组转换为List coursesToSelect.addAll(Arrays.asList(course)); Course temp3 = (Course) coursesToSelect.get(2); Course temp4 = (Course) coursesToSelect.get(3);// System.out.println("添加了两门课程:"+temp3.id+":"+temp3.name+";"// +temp4.id+":"+temp4.name); //创建一个课程数组,并通过调用addAll(int index, Arrays.asList(course))方法,添加到备选课程中 Course[] course2 = { new Course("5","高等数学"), new Course("6","大学英语") }; coursesToSelect.addAll(2, Arrays.asList(course2)); Course temp5 = (Course) coursesToSelect.get(2); Course temp6 = (Course) coursesToSelect.get(3);// System.out.println("添加了两门课程:"+temp5.id+":"+temp5.name+";"// +temp6.id+":"+temp6.name); } /** * 通过for each方法访问元素 * @param args */ public void testForEach() { System.out.println("有如下课程待选(通过for each访问):"); for(Object obj:coursesToSelect) { /** * 当一个元素被存入集合时,它的类型被忽略,集合只把它当做Object, * 当取出来的时候,还是Object类型,要强转换为原来类型 */ Course cr = (Course) obj; System.out.println("课程:"+cr.id+":"+cr.name); } } /** * 测试List的contains方法 */ public void testListContains() { /** * contains(obj)的原理: * 遍历List中的每个元素,然后equals(obj), * 只要有返回为true的,证明包含该对象, * 因此返回true。否则返回false */ //取得备选课程序列的第0个元素 Course course = coursesToSelect.get(0); //打印输出coursesToSelect是否包含course对象 System.out.println("取得课程:"+course.name); System.out.println("备选课程中是否包含课程:"+course.name+","+coursesToSelect.contains(course));//true/重写equals()后true //创建新的课程对象,ID和名称与course相同 Course course2 = new Course(course.id,course.name); System.out.println("取得课程:"+course2.name); System.out.println("备选课程中是否包含课程:"+course2.name+","+coursesToSelect.contains(course2));//false/重写equals()后true //course 和course2虽然ID和名称相同,但是是两个不同的对象,因此返回false //仅通过name判断List中是否包含该课程 //在Course中重写equals方法即可 //重写之后,判断name相同,则对象相同,contains()返回true //从键盘输入课程名称,判断是否包含 System.out.println("请输入课程名称:"); String name = console.next(); //创建course3,使用无参构造器,然后name赋值 Course course3 = new Course(); course3.name = name; System.out.println("取得课程:"+course3.name); System.out.println("备选课程中是否包含课程:"+course3.name+","+coursesToSelect.contains(course3)); //containsAll()判断是否包含多个元素 } /** * 创建学生对象并选课 */ public void createStudentAndSelectCourse() { //创建一个学生对象// Student student = new Student("1","小明"); /** * 类中声明了public Student student,在这里不能再创建新的对象, * 直接将student实例化即可, * 否则testSetContains()最后一行会报空指针异常 */ student = new Student("1","小明"); System.out.println("欢迎学生"+student.name+"选课!"); //创建Scanner对象,用来接收从键盘输入的课程ID Scanner console = new Scanner(System.in); for(int i=0;i<3;i++){ System.out.println("请输入课程ID"); String courseId = console.next(); for (Course cr : coursesToSelect) { if(cr.id.equals(courseId)) { student.courses.add(cr); /** * Set中添加某个对象,无论重复添加多少次, * 最终只保留一个该对象(的引用), * 并且保留的是第一次添加的那个 * 因为Set元素不重复 */ //student.courses.add(cr); /** * 添加null不报错, * 但是对实际情况没有任何作用, * 因此一般不这么写 */ //student.courses.add(null); } } } } /** * 测试Set的contains方法 */ public void testSetContains() { //提示输入课程名称 System.out.println("请输入学生已选的课程名称:"); String name = console.next(); Course course = new Course(); course.name = name; System.out.println("取得课程名称:"+course.name); /** * 类中声明了public Student student, * createStudentAndSelectCourse()中不能再创建新的对象,直接将student实例化即可, * 否则下行会报空指针异常 */ System.out.println("备选课程中是否包含课程"+course.name+","+student.courses.contains(course)); } /** * * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub SetTest st = new SetTest(); st.testAdd();// st.testListContains(); st.testForEach(); st.createStudentAndSelectCourse(); st.testSetContains(); } public void testForEachForSet(Student student) { //打印输出,学生所选的课程 System.out.println("共选择了"+student.courses.size()+"门课程"); for (Course cr : student.courses) { System.out.println("选择了课程:"+cr.id+":"+cr.name); } //循环遍历Set中的元素只能使用foreach和iterator方法,不能像List一样还能使用get方法 //因为Set是无序的,本身并不能够查找指定位置上的元素 }}
获取List中课程的位置
使用indexOf()方法
indexOf()原理
/** * 测试List的contains方法 */ public void testListContains() { /** * contains(obj)的原理: * 遍历List中的每个元素,然后equals(obj), * 只要有返回为true的,证明包含该对象, * 因此返回true。否则返回false */ //仅通过name判断List中是否包含该课程 //在Course中重写equals方法即可 //重写之后,判断name相同,则对象相同,contains()返回true //从键盘输入课程名称,判断是否包含 System.out.println("请输入课程名称:"); String name = console.next(); //创建course3,使用无参构造器,然后name赋值 Course course3 = new Course(); course3.name = name; System.out.println("取得课程:"+course3.name); System.out.println("备选课程中是否包含课程:"+course3.name+","+ coursesToSelect.contains(course3)); //containsAll()判断是否包含多个元素 //通过indexOf()方法来取得某元素的索引位置 if(coursesToSelect.contains(course3)) { System.out.println("课程:"+course3.name+"的索引位置为:"+ coursesToSelect.indexOf(course3)); } }
判断Map中是否包含指定的key和value
Student.java
重写equals()方法,自动生成,仅选择属性name
import java.util.HashSet;import java.util.Set;/** * 学生类 * @author Wang Jiaxin * */public class Student { public String id; public String name; public Set courses; public Student(String id,String name) { this.id = id; this.name = name; this.courses = new HashSet(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Student other = (Student) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } }
MapTest.java
testContainsKeyOrValue()
import java.util.HashMap;import java.util.Map;import java.util.Map.Entry;import java.util.Scanner;import java.util.Set;public class MapTest { /** * 用来承装学生类型对象 * @param args */ public Map students; private Scanner console; /** * 在构造器中初始化students属性 */ public MapTest() { this.students = new HashMap(); console = new Scanner(System.in);//Scanner对象初始化 } /** * 测试添加:输入学生ID,判断是否被占用 * 若未被占用,则输入姓名,创建新学生对象 * 并且添加到students中 */ public void testPut() { //创建一个Scanner对象,用来获取输入的学生ID和姓名 Scanner console = new Scanner(System.in); int i=0; while(i<3) { System.out.println("请输入学生ID"); String ID = console.next(); //判断该ID是否被占用 Student st = students.get(ID); if(st == null) { //提示输入学生姓名 System.out.println("请输入学生姓名:"); String name = console.next(); //创建新的学生对象 Student newStudent = new Student(ID,name); //通过调用students的put方法,添加ID-学生映射 students.put(ID,newStudent); System.out.println("成功添加学生:"+students.get(ID).name); i++; }else { System.out.println("该学生ID已被占用"); continue; } } } /** * 测试Map的keySet方法 */ public void testKeySet() { //通过keySet方法,返回Map中的所有key的Set集合 Set keySet = students.keySet(); //取得students的容量 System.out.println("总共有"+students.size()+"个学生"); //遍历keySet,取得每一个key,再调用get方法取得每个key对应的value值 for (String stuId : keySet) { Student st = students.get(stuId); if(st != null) { System.out.println("学生:"+st.name); } } } /** * 测试删除Map中的映射 */ public void testRemove() { //获取从键盘输入的学生ID Scanner console = new Scanner(System.in); while(true) { //提示输入待删除的学生ID System.out.println("请输入要删除的学生ID"); String ID = console.next(); //判断该ID是否有对应的学生对象 Student st = students.get(ID); if(st == null) { //提示输入的ID并不存在 System.out.println("该ID不存在"); continue; }else { students.remove(ID); System.out.println("成功删除学生:"+st.name); break; } } } /** * 通过entrySet方法来遍历Map */ public void testEntrySet() { //通过entrySet方法,返回Map中的所有键值对 Set> entrySet = students.entrySet(); for (Entry entry : entrySet) { System.out.println("取得键:"+entry.getKey()); System.out.println("对应的值为:"+entry.getValue().name); } } /** *利用put方法修改Map中的已有映射 */ public void testModify() { //提示输入要修改的学生ID System.out.println("请输入要修改的学生ID"); Scanner console = new Scanner(System.in); while(true) { String stuID = console.next(); //从students中查找该学生ID对应的学生,没有的话要重新输入 Student student = students.get(stuID); if(student == null) { System.out.println("该ID不存在"); continue; }else { System.out.println("当前该学生ID,所对应的的学生为"+student.name); //提示输入新的学生姓名,来修改已有的映射 System.out.println("请输入新的学生姓名"); String name = console.next(); Student newStudent = new Student(stuID,name); students.put(stuID, newStudent); System.out.println("修改成功!"); break; } } } /** * 测试Map中是否包含某个Key值或者某个Value值 */ public void testContainsKeyOrValue() { //提示输入ID System.out.println("请输入要查询的学生ID"); String id = console.next(); //在Map中,用containsKey()来判断是否包含某个Key值 System.out.println("您输入的学生ID为:"+id+",在学生映射表中是否存在:" +students.containsKey(id)); if(students.containsKey(id)) { System.out.println("对应的学生为:"+ students.get(id).name); } //提示输入name System.out.println("请输入要查询的学生姓名"); String name = console.next(); //用containsValue()来判断是否包含某个Value值 System.out.println("您输入的学生姓名为:"+name+",在学生映射表中是否存在:" +students.containsValue(new Student(null,name))); //此处返回false,重写Student类的equals方法,eclipse自动生成,只选择name属性 if(students.containsValue(new Student(null,name))) { System.out.println("在学生映射表中,确实包含学生:"+name); }else { System.out.println("在学生映射表中不存在该学生"); } } /** * * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub MapTest mt = new MapTest(); mt.testPut(); mt.testKeySet();// mt.testRemove();// mt.testEntrySet();// mt.testModify();// mt.testEntrySet(); mt.testContainsKeyOrValue(); }}
应用Collection.sort()实现List排序
Collection工具类
是java集合框架中,用来操作集合对象的工具类,也是java集合框架的成员
sort() 排序方法
comparable —— 可比较的 默认比较规则
* 实现该接口表示:这个类的实例可以比较大小,可以进行自然排序
* 定义了默认的比较规则
* 其实现类需要实现compareTo()方法
* compareTo()方法返回正数表示大,负数表示小,0表示相等
Comparator —— 比较工具接口 临时比较规则
* 用于定义临时比较规则,而不是默认比较规则
* 其实现类需要实现compare()方法
* Comparator和Comparable都是java集合框架的成员
ComparableStudent.java
针对testSort3()方法 ——继承接口Comparable,实现compareTo,比较id
import java.util.HashSet;import java.util.Set;/** * 学生类 * @author Wang Jiaxin * */public class Student implements Comparable<Student> { public String id; public String name; public Set courses; public Student(String id,String name) { this.id = id; this.name = name; this.courses = new HashSet(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Student other = (Student) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } @Override public int compareTo(Student o) { // TODO Auto-generated method stub //将两个对象的id比较结果作为两个对象的比较结果返回 return this.id.compareTo(o.id); } }
ComparatorStudentComparator.java
针对testSort3()方法 ——继承接口Comparator,实现方法compare,比较name
import java.util.Comparator;public class StudentComparator implements Comparator<Student> { @Override public int compare(Student arg0, Student arg1) { // TODO Auto-generated method stub return arg0.name.compareTo(arg1.name); }}
CollectionsTest.java
三种排序方式,第三种分别用comparable和comparator进行排序
import java.util.ArrayList;import java.util.Collections;import java.util.List;import java.util.Random;import java.util.Scanner;/** * 将要完成: * 1.通过Collections.sort()方法,对Integer泛型的List进行排序 * 2.对String泛型的List进行排序 * 3.对其他类型泛型的List进行排序,以Student为例 * @author Wang Jiaxin * */public class CollectionsTest { /** * 1.通过Collections.sort()方法,对Integer泛型的List进行排序 * 创建一个Integer泛型的List,插入10个100以内的不重复的随机整数, * 调用Collections.sort()方法对其进行排序 */ public void testSort1() { List integerList = new ArrayList(); //插入10个100以内的不重复的随机整数, Random random = new Random(); Integer k; for(int i=0;i<10;i++) { do { k = random.nextInt(100); }while(integerList.contains(k)); integerList.add(k); System.out.println("成功添加整数:"+k); } System.out.println("-----------排序前----------"); for (Integer integer : integerList) { System.out.println("元素"+integer); } Collections.sort(integerList); System.out.println("-----------排序后----------"); for (Integer integer : integerList) { System.out.println("元素"+integer); } } /** * 2.对String泛型的List进行排序 * 创建String泛型的List,添加3个乱序的String元素 * 调用sort方法,在此输出排序后的顺序 */ public void testSort2() { List stringList = new ArrayList(); //添加3个乱序的String元素 stringList.add("microsoft"); stringList.add("google"); stringList.add("lenovo"); System.out.println("-----------排序前----------"); for (String string : stringList) { System.out.println("元素"+string); } Collections.sort(stringList); System.out.println("-----------排序后----------"); for (String string : stringList) { System.out.println("元素"+string); } } /** * 3.对其他类型泛型的List进行排序,以Student为例 * id为1000以内的随机数 */ public void testSort3() { List studentList = new ArrayList(); List integerList = new ArrayList(); Random random = new Random(); //请稍后修改为id不可重复 int[] index = new int[3]; int k; int i=0; while(i<3) { k = random.nextInt(1000); for (int i1 : index) { if(i1==k) { continue; }else { index[i] = k; i++; break; } } } studentList.add(new Student(index[0]+"","Mike")); studentList.add(new Student(index[1]+"","Angela")); studentList.add(new Student(index[2]+"","Lucy")); // studentList.add(new Student(random.nextInt(1000)+"","Mike"));// studentList.add(new Student(random.nextInt(1000)+"","Angela"));// studentList.add(new Student(random.nextInt(1000)+"","Lucy")); System.out.println("-----------排序前----------"); for (Student student : studentList) { System.out.println("元素"+student.id+":"+student.name); } /** * 列表中的所有元素都必须实现Comparable接口,可比较的,定义默认比较规则, * 下句会报编译错误,因此需要对Student类进行改造 * 让Student继承Comparable接口,并实现compareTo()方法,具体见Student类 */ Collections.sort(studentList); /** * 排序方式,按照id排序 * 由于id为String类型,按照先比较第一位0-9 a-z A-Z的大小进行比较 * 如果id为int类型,则直接比较大小 */ System.out.println("-----------排序后----------"); for (Student student : studentList) { System.out.println("元素"+student.id+":"+student.name); } /** * 使用comparator排序,使用的是两个参数的sort()方法 * 让StudentComparator继承Comparator接口,并实现compare()方法,具体见StudentComparator类 */ Collections.sort(studentList, new StudentComparator()); System.out.println("-----------按照姓名排序后-----------"); for (Student student : studentList) { System.out.println("元素"+student.id+":"+student.name); } } /** * * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub CollectionsTest ct = new CollectionsTest(); ct.testSort3(); }}