java中集合框架概述
- collection集合框架存储对象,有多个接口list,queue,set。他们对应的重要实现类分别是ArrayList,LinkedList,HashSet
定义类图
public class Course {
public String id;
public String name;
public Course(String id,String name){
this.id=id;
this.name=name;
}
public Course(){
}
}
public class Student {
public String id;
public String name;
public Set<Course> courses;
public Student(String id,String name){
this.id=id;
this.name=name;
this.courses=new HashSet<Course>();
}
}
使用List接口
/*
- 备选课程类
*/
public class ListTest {
public List courseToSelect;
/*
* 用于存放备选课程的list
*/
public ListTest(){
this.courseToSelect = new ArrayList();
}
/*
* 用于往coursetoselect中添加备选课程
*/
public void testAdd(){
//创建一个课程对象并通过调用add方法,添加到备选课程list中
Course cr1= new Course("1","数据结构");
courseToSelect.add(cr1);
Course temp= (Course) courseToSelect.get(0);
//System.out.println("添加了课程:"+temp.id+":"+temp.name);
Course cr2 = new Course("2","c语言");
courseToSelect.add(0, cr2);
Course temp2=(Course)courseToSelect.get(0);
//System.out.println("添加了课程:"+temp2.id+":"+temp2.name);
courseToSelect.add(cr1);
Course temp0= (Course) courseToSelect.get(2);
//System.out.println("添加了课程:"+temp0.id+":"+temp0.name);
//以下会抛出数组下标越界异常
//Course cr3 = new Course("3","cdsfsf");
//courseToSelect.add(4, cr3);
Course[] course={new Course("3","离散数学"),new Course("4","汇编语言")};
courseToSelect.addAll(Arrays.asList(course));
Course temp3=(Course)courseToSelect.get(3);
Course temp4=(Course)courseToSelect.get(4);
//System.out.println("添加了两门课程:"+temp3.id+":"+
//temp3.name+";"+temp4.id+":"+temp4.name);
Course[] course2={new Course("5","高等数学"),new Course("6","大学英语")};
courseToSelect.addAll(2, Arrays.asList(course2));
Course temp5=(Course)courseToSelect.get(2);
Course temp6=(Course)courseToSelect.get(3);
//System.out.println("添加了两门课程:"+temp5.id+":"+
//temp5.name+";"+temp6.id+":"+temp6.name);
}
/*
* 取得List中的元素的方法
*/
public void testGet(){
int size =courseToSelect.size();
System.out.println("有如下课程待选:");
for(int i=0;i<size;i++){
Course cr = (Course) courseToSelect.get(i);
System.out.println("课程:"+cr.id+cr.name);
}
}
/*
* 通过迭代器遍历List
*/
public void testIterator(){
//通过集合的Iterator方法
Iterator it = courseToSelect.iterator();
System.out.println("有如下课程待选(通过迭代器访问):");
while(it.hasNext()){
Course cr =(Course)it.next();
System.out.println("课程:"+cr.id+cr.name);
}
}
/*
* 通过foreach方法访问集合元素
*/
public void testForEach(){
System.out.println("有如下课程待选(通过for each)):");
for(Object obj:courseToSelect){
//当元素被存入集合,其类型被忽略为object
Course cr =(Course)obj;
System.out.println("课程:"+cr.id+cr.name);
}
}
/*
* 修改list中的元素
*/
public void testModify(){
courseToSelect.set(4, new Course("7","毛概"));
}
/*
* 删除list中的元素
*/
public void testRemove(){
// Course cr =(Course)courseToSelect.get(4);
// System.out.println("我是课程"+":"+cr.name+" 我即将被删除");
//System.out.println("即将删除4位置上的课程!");
//courseToSelect.remove(4);
System.out.println("即将删除4位置和5 位置上的课程!");
Course[] courses ={(Course) courseToSelect.get(4),(Course) courseToSelect.get(5)};
courseToSelect.removeAll(Arrays.asList(courses));
System.out.println("成功珊瑚课程!");
testForEach();
}
/*
* 往list中添加一些奇怪的东西
*
*/
// public void testType(){
// System.out.println("能否在list");
// courseToSelect.add("字符串");
// //不能,用泛型规定添加的元素类型
// }
public static void main(String[] args){
ListTest lt=new ListTest();
lt.testAdd();
lt.testForEach();
}
}
应用泛型管理课程
public class TestGeneric {
/*
* 带有泛型---course,的list类型属性
*/
public List<Course> courses;
public TestGeneric(){
this.courses=new ArrayList<Course>();
}
/*
* 测试添加
*/
public void testAdd(){
Course cr1 =new Course("1","大学语文");
courses.add(cr1);
//courses.add("能否添加一些奇怪的东西呢???");//当然不能。编译期间检查,不是泛型规定的类型,报错
//泛型集合中。不能添加 泛型规定的类型及其子类型以外的对象,否则会报错!
Course cr2 = new Course("2","java basic");
courses.add(cr2);
}
/*
* 测试循环遍历
*/
public void testForEach(){
for(Course cr:courses){
System.out.println(cr.id+":"+cr.name);
}
}
/*
* 泛型集合可以添加泛型的子类型的对象实例
*/
public void testChild(){
ChildCourse ccr = new ChildCourse();
ccr.id="3";
ccr.name="我是子类型的课程对象实例";
courses.add(ccr);
}
/*
* 泛型不能使用基本类型
*/
public void testBasicType(){
List<Integer> list = new ArrayList<Integer>();
//注意泛型中的限定类型不能使用基本类型,可以通过使用包装类
list.add(1);
System.out.println("基本类型必须使用包装类作为泛型!"+list.get(0));
}
public static void main(String[] args) {
// TODO Auto-generated method stub
TestGeneric tg=new TestGeneric();
tg.testAdd();
tg.testForEach();
tg.testChild();
tg.testForEach();
tg.testBasicType();
}
}
public class ChildCourse extends Course {
}
使用set集合
public class SetTest {
public List<Course> courseToSelect;
public SetTest(){
courseToSelect = new ArrayList<Course>();
}
public void testAdd(){
//创建一个课程对象并通过调用add方法,添加到备选课程list中
Course cr1= new Course("1","数据结构");
courseToSelect.add(cr1);
Course cr2 = new Course("2","c语言");
courseToSelect.add(0, cr2);
Course[] course={new Course("3","离散数学"),new Course("4","汇编语言")};
courseToSelect.addAll(Arrays.asList(course));
Course[] course2={new Course("5","高等数学"),new Course("6","大学英语")};
courseToSelect.addAll(2, Arrays.asList(course2));
}
public void testForEach(){
System.out.println("有如下课程待选(通过for each)):");
for(Object obj:courseToSelect){//当元素被存入集合,其类型被忽略为object
Course cr =(Course)obj;
System.out.println("课程:"+cr.id+cr.name);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
SetTest st = new SetTest();
st.testAdd();
st.testForEach();
Student student = new Student("1","Ming");
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 :st.courseToSelect){
if(cr.id.equals(courseId)){
student.courses.add(cr);
/*
* set中,添加某个对象,无论添加多少次
* 最终只保留一个该对象(的引用)
* 并且,保留的是第一次添加的那一个
*/
//student.courses.add(null);//可以添加空对象,但是没什么意义
}
}
}
st.testForEachforSet(student);
}
public void testForEachforSet(Student student){
//打印输出,学生所选的课程!
System.out.println("共选择了:"+student.courses.size()+"门课程");
for(Course cr:student.courses){
System.out.println("选择了课程:"+cr.id+cr.name);
}
}
}
使用map接口
-
map提供映射关系,以键值对存储。
代码示例
public class MapTest {
/*
* 用来承装学生类型对象
*/
public Map<String,Student>students;
/*
* 在构造器中初始化student属性
*/
public MapTest(){
this.students = new HashMap<String,Student>();
}
/*
* 测试添加:输入学生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);
//通过调用studnets的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中的所有“键”的set集合
Set<String> keySet = students.keySet();
//取得stuents的容量
System.out.println("总共有:"+students.size()+"个学生");
//遍历keyset,取得每一个键,在调用get方法取得每个键对应的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;
}
students.remove(ID);
System.out.println("成功删除学生:"+st.name);
break;
}
}
/*
* 通过entrySet方法来遍历Map
*/
public void testEntrySet(){
//通过entrySet该方法,返回map中所有键值对
Set<Entry<String,Student>> entrySet= students.entrySet();
for(Entry<String,Student> entry:entrySet){
System.out.println("取得键:"+entry.getKey());
System.out.println("对应的值为"+entry.getValue().name);
}
}
/*
* 利用put方法修改map中的已有映射
*/
public void testModify(){
//提示输入要修改的学生ID
System.out.println("请输入要修改的学生ID:");
//创建scanner对象,获取从键盘上输入的学生ID字符串
Scanner console = new Scanner(System.in);
while(true){
String stuID= console.next();
//从tsudnets中差好啊该学生ID对应的学生对象
Student student= students.get(stuID);
if(student ==null){
System.out.println("该ID不存在!请重新输入!");
continue;
}
//提示当前对应的学生对象的姓名
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;
}
}
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();
}
}
判断是否包含某元素
利用contains方法
- 该方法从collection继承来
- 下面测试list和set的contains方法
测试set的contains方法
public void testListContains(){
//取得备选课程序列的第0个元素
Course course = courseToSelect.get(0);
//打印输出courseToSelect是否包含course对象
System.out.println("取得课程:"+course.name);
System.out.println("备选课程中是否包含课程:"+course.name+","+courseToSelect.contains(course));
//包含返回true,不包含返回false
//创建一个新的课程对象,ID和名称,与course对象完全一样
Course course2 = new Course(course.id,course.name);
System.out.println("新创建课程:"+course2.name);
System.out.println("备选课程中是否包含课程"+course2.name+","+courseToSelect.contains(course2));//**这里是false**
}
- 所有类都继承自object 有一个equals(Object obj)方法
- contains(obj)方法实际是遍历其中每一个元素,调用每个元素的equals方法与参数obj比较,所有都不相同,才返回false
- 通过重写equals方法可以实现通过contains是否包含名称为某个值的课程元素
在Course类中重写equals方法
//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))
return true;
else
return false;
}
}
注:该equlas重写方法可以作为一个模板使用
这之后运行setTest
其中System.out.println("备选课程中是否包含课程"+course2.name+","+courseToSelect.contains(course2));//
得到的这里是true,说明equals方法重载成功。
object中还有一个方法:hashCode()返回该对象的哈希码的值
-
当调用contains(obj)的时候,先调用每一个元素的hashcode(),相等再调用equals()。只有认为这两个方法返回的值都相等的时候,才认定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 (!(obj instanceof Course)) 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;
}
Ecilpse可以自动生成hashcode和equals方法。
判断元素的索引位置
//通过indexof方法来获取某元素的索引位置
if(courseToSelect.contains(course2))
System.out.println("课程:"+course2.name+"的索引位置为"+courseToSelect.indexOf(course2));
- indexof(java)从0开始遍历,逐个进行equals(java)比较,若返回true,得到元素的索引位置。如果有多个重复元素,返回第一个元素的索引位置
- lastIndexOf(java)方法与indexof相反,从最后开始遍历
- 若没有找到该元素,这两个方法都返回-1
判断map中是否包含指定的key和value值
/*
* 测试map中,是否包含某个key值或者某个value值
*/
public void testContainsKeyOrValue(){
System.out.println("请输入要查询的学生ID");
Scanner console = new Scanner(System.in);
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);
System.out.println("请输入要查询的学生姓名:");
String name = console.next();
//用containsValue()方法,来判断是否包含某个Value值
if(students.containsValue(new Student(null,name)))
System.out.println("在学生映射表中,确实包含学生:"+name);
else{
System.out.println("在学生映射表中不存在该学生");
}
}
【注】这里的查询是否包含学生姓名的时候contain方法仍然调用了hashcode和equals方法,所以要在student类中重载两个方法
应用collection.sort()实现list排序
- java.util.collections工具类,提供了许多静态方法,用来操作集合
- 用collection.sort()实现list排序
/*
- 将要完成:
- 1.通过Collections.sort()方法,对Integer泛型的list进行排序
- 2.对String泛型的List进行排序
- 3.对其他类型泛型的list进行排序,以student为例
*/
public class CollectionsTest {
/*
* 1.通过Collections.sort()方法,对Integer泛型的list进行排序
* 创建一个Integer泛型的list,插入是个100以内不重复的随机数
* 调用Collections.sort()方法排序
*/
public void testSort1(){
List<Integer> integerList = new ArrayList<Integer>();
//插入是个100以内不重复的随机数
Random random = new Random();
Integer k = null;
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,添加三个乱序的String
* 调用sort方法,再次输出排序后的顺序
*/
public void testSort2(){
List<String> stringList = new ArrayList<String>();
stringList.add("microsoft");
stringList.add("google");
stringList.add("eldasdaf");
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为例
*/
public void testSort3(){
//....
}
}
comparable与comparator接口
- comparable默认比较规则,可比较的,实现改接口表示:这个类的示例可以bijou大小。可以进行自然排序。
public class Student implements Comparable<Student>{
@Override
public int compareTo(Student o) {
// TODO Auto-generated method stub
return this.id.compareTo(o.id);
}
public void testSort3(){
List<Student> studentList = new ArrayList<Student>();
Random random = new Random();
studentList.add(new Student(random.nextInt(1000)+"","mike"));
studentList.add(new Student(random.nextInt(1000)+"","xixo"));
studentList.add(new Student(random.nextInt(1000)+"","Lan"));
System.out.println("--------排序前-----------");
for (Student student : studentList) {
System.out.println("学生:"+student.id+":"+student.name);
}
Collections.sort(studentList);
System.out.println("--------排序后-----------");
for (Student student : studentList) {
System.out.println("学生:"+student.id+":"+student.name);
}
}
- comparator 定义临时比较规则
public class StudentComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
// TODO Auto-generated method stub
return o1.name.compareTo(o2.name);
}
}
public void testSort3(){
List<Student> studentList = new ArrayList<Student>();
Random random = new Random();
studentList.add(new Student(random.nextInt(1000)+"","mike"));
studentList.add(new Student(random.nextInt(1000)+"","xixo"));
studentList.add(new Student(random.nextInt(1000)+"","Lan"));
studentList.add(new Student(10000+"","beyonce"));
//这里按照姓名排序
Collections.sort(studentList,new StudentComparator());
System.out.println("---------按照姓名排序后---------");
for (Student student : studentList) {
System.out.println("学生:"+student.id+":"+student.name);
}
}
总结
所有类图
github地址:Elylicery
https://github.com/Elylicery/Code-Exercise/tree/master/imooc-collection-demo