Java 集合框架
2015-11-29 12:34
423 查看
Java 集合框架
转载自:https://www.shiyanlou.com/courses/document/1120实验介绍
本实验讲学习 Java 集合框架里的接口、具体类和算法的相关知识一、集合框架的介绍
我们在超市买东西的时候,如果没有购物车是不是会很麻烦呢?Java 中集合类是一种工具类,就是像购物车一样的容器,存储任意数量的具有共同属性的对象。我们为什么要用集合呢?一个类的内部有许多相同类型的属性,并且他们的作用与意义是一样的,我们最好用一个类似容器的东西去盛放他们,在类的内部就变得井然有序。所以集合便是在类的内部,对数据进行组织的作用。这样我们便可以简单而快速地搜索大量的条目。有的集合接口,提供了一系列排列有序的元素,并且可以在序列中快速地插入或者删除有关元素。还有一些集合接口,提供了映射关系,可以通过关键字(key)去快速查找到对应的唯一对象,而这个关键字可以是任意类型。
集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。任何集合框架都包含三大内容:对外的接口、接口的实现和对集合运算的算法。
二、接口
因为集合框架中的很多类功能是相似的,所以我们用接口来规范类。Collextion 接口是 java 集合框架里的一个根接口。它也是 List、Set 和 Queue 接口的父接口。Collection 接口中定义了可用于操作 List、Set 和 Queue 的方法——增删改查。方法 | 返回值 | 说明 |
---|---|---|
add(E e) | boolean | 向列表的尾部追加指定的元素(可选操作) |
add(int index, E element) | void | 在列表的指定位置插入指定元素(可选操作) |
addAll(Collection c) | boolean | 追加指定 collection 中的所有元素到此列表的结尾,顺序是指定 collection 的迭代器返回这些元素的顺序(可选操作) |
addAll(int index, Collection c) | boolean | 将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作) |
clear() | void | 从列表中移除所有元素(可选操作) |
contains(Object o) | boolean | 如果列表包含指定的元素,则返回 true |
containsAll(Collection c) | boolean | 如果列表包含指定 collection 的所有元素,则返回 true |
equals(Object o) | boolean | 比较指定的对象与列表是否相等 |
get(int index) | 返回列表中指定位置的元素 | |
hashCode() | int | 返回列表的哈希码 |
indexOf(Object o) | int | 返回列表中首次出现指定元素的索引,如果列表不包含此元素,则返回 -1 |
isEmpty() | boolean | 如果列表不包含元素,则返回true |
iterator() | Iterator | 返回以正确顺序在列表的元素上进行迭代的迭代器 |
lastIndexOf(Object o) | int | 返回列表中最后出现指定元素的索引,如果列表不包含此元素,则返回-1 |
listIterator() | ListIterator | 返回列表中元素的列表迭代器(以正确的顺序) |
listIterator(int index) | ListIterator | 返回列表中元素的列表迭代器(以正确的顺序),从列表的指定位置开始 |
remove(Object o) | boolean | 移除列表中出现的首个指定元素(可选操作) |
removeAll(Collection c) | boolean | 从列表中移除指定 collection 中包含的所有元素(可选操作) |
retainAll(Collection c) | boolean | 仅在列表中保留指定 collection 中包含的元素(可选操作) |
set(int index, E element) | E | 用指定元素替换列表中指定位置的元素(可选操作) |
size() | int | 返回列表中的元素数 |
subList(int fromIndex, int toIndex) | List | 返回列表中指定的 fromIndex(包括)和 toIndex(不包括)之间的部分视图 |
toArray() | Object[] | 返回以正确顺序包含列表中的所有元素的数组 |
toArray() | T[] | 返回以正确顺序包含列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型 |
Map 接口也是一个非常重要的集合接口,用于存储键/值对。Map 中的元素都是成对出现的,键值对就像数组的索引与数组的内容的关系一样,将一个键映射到一个值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。我们可以通过键去找到相应的值。
value 可以存储任意类型的对象,我们可以根据 key 值快速查找 value。Map 中的键值对以 Entry 类型的对象实例形式存在
看一看 Map 中的方法吧
方法 | 返回值 | 说明 |
---|---|---|
clear() | void | 从映射中移除所用映射关系(可选操作) |
containsKey() | boolean | 如果此映射将一个或多个键映射到指定值,则返回true |
entrySet | Set |
三、具体类
1、List 接口与 ArrayList 类
List 是一个接口,不能实例化,需要一个具体类来实现实例化。List 集合中的对象按照一定的顺序排放,里面的内容可以重复。 List 接口实现的类有:ArrayList(实现动态数组),Vector(实现动态数组),LinkedList(实现链表),Stack(实现堆栈)。今天我们主要来学习 java.util.ArrayList,ArrayList 类实现一个课增长的动态数组,它可以存储不同类型的对象,而数组则只能存放特定数据类型的值。
我们通过实际的例子来学习ArrayList吧!学校的教务系统会对学生进行统一的管理,每一个学生都会有一个学号和学生姓名,我们在维护整个系统的时候,大多数操作是对学生的添加、插入、删除、修改等操作。
先创建一个学生类:
package com.shiyanlou.test_collection_demo; /* * 学生类 */ public class Student { public String id; public String name; public Student(String id, String name){ this.id = id; this.name = name; } }
再创建一个学生列表,来管理学生
package com.shiyanlou.test_collection_demo; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; /* * 管理学生类 */ public class ListTest { /* * 用于存放学生的List */ public List students; public ListTest() { this.students = new ArrayList(); } /* * 用于往students中添加学生 */ public void testAdd() { //创建一个学生对象,并通过调用add方法,添加到学生管理List中 Student st1 = new Student('1', '张三'); students.add(st1); //添加到List中的类型均为Object,所以取出时还需要强转 Student temp = (Student)students.get(0); System.out.println('添加了学生:' + temp.id + ':' + temp.name); Student st2 = new Student('2','李四'); students.add(0, st2); Student temp2 = (Student)students.get(0); System.out.println('添加了学生:' + temp2.id + ':' +temp2.name); Student[] student = {new Student('3', '王五'),new Student('4', '马六')}; students.addAll(Arrays.asList(student)); Student temp3 = (Student)students.get(2); Student temp4 = (Student)students.get(3); System.out.println('添加了学生:' + temp3.id + ':' +temp3.name); System.out.println('添加了学生:' + temp4.id + ':' +temp4.name); Student[] student2 = {new Student('5', '周七'),new Student('6', '赵八')}; students.addAll(2,Arrays.asList(student2)); Student temp5 = (Student)students.get(2); Student temp6 = (Student)students.get(3); System.out.println('添加了学生:' + temp5.id + ':' +temp5.name); System.out.println('添加了学生:' + temp6.id + ':' +temp6.name); } /* * 取得List中的元素的方法 */ public void testGet() { int size = students.size(); for(int i = 0;i<size;i++){ Student st = (Student)students.get(i); System.out.println('学生:' + st.id+':'+ st.name); } } /* * 通过迭代器来遍历 */ public void testIterator() { //通过集合的iterator方法,取得迭代器实例 Iterator it = students.iterator(); System.out.println('有如下学生(通过迭代器访问):'); while(it.hasNext()){ Student st = (Student)it.next(); System.out.println('学生' + st.id + ':' +st.name); } } /** * 通过for each 方法访问集合元素 * @param args */ public void testForEach() { System.out.println('有如下学生(通过for each):'); for(Object obj:students){ Student st = (Student)obj; System.out.println('学生:' + st.id + ':' + st.name); } } /** * 修改List中的元素 * @param args */ public void testModify(){ students.set(4,new Student('3','吴酒')); } /** * 删除List中的元素 * @param args */ public void testRemove() { Student st = (Student)students.get(4); System.out.println('我是学生:' + st.id + ':' + st.name + ',我即将被删除'); students.remove(st); System.out.println('成功删除学生!'); testForEach(); } public static void main(String[] args) { ListTest lt = new ListTest(); lt.testAdd(); lt.testGet(); lt.testIterator(); lt.testModify(); lt.testForEach(); lt.testRemove(); } }
大家看懂了吗?自己实操一下吧。
LinkedList 类是用于创建链表数据结构,使用 LinkList 的好处在于它具有访问、检索和删除数据的方法,特别是添加或移除对象时,LinkedList 的表现更佳。但是底层依然必须遍历去查找随机访问的对象,因此性能依然有限。它与 ArrayList 有许多相似之处,在这里便不详细讲解了
2、Set 接口和 HashSet 类
Set接口也是 Collection 接口的子接口,它有一个很重要也是很常用的实现类——HashSet,Set 是元素无序并且不可以重复的集合(List 可以重复),被称为集。接下来我们同样通过代码的形式来详细看一看吧!
在上面我们实现了学生的管理,现在学生要做项目,每个项目有一个组长,由组长来组织组员,我们便来实现项目组的管理吧。(接上面的程序实例)
因为项目组的组长由一个老师担任,首先我们来创建一个 PD 类
package com.shiyanlou.test_collection_demo; import java.util.HashSet; import java.util.Set; /* * 项目组长类 */ public class PD { public String id; public String name; //集合后面的<>代表泛型的意思 //泛型是规定了集合元素的类型 //我们以后会详细讲到 public Set<Student> students; public PD(String id, String name){ this.id = id;s this.name = name; this.students = new HashSet<Student>(); } }
接下来我们便创建一个SetTest 类,用来管理项目成员
package com.shiyanlou.test_collection_demo; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Scanner; public class SetTest { public List<Student> students; public SetTest() { students = new ArrayList<Student>(); } /* * 用于往students中添加学生 */ public void testAdd() { //创建一个学生对象,并通过调用add方法,添加到学生管理List中 Student st1 = new Student('1', '张三'); students.add(st1); //添加到List中的类型均为Object,所以取出时还需要强转 Student st2 = new Student('2','李四'); students.add(st2); Student[] student = {new Student('3', '王五'),new Student('4', '马六')}; students.addAll(Arrays.asList(student)); Student[] student2 = {new Student('5', '周七'),new Student('6', '赵八')}; students.addAll(Arrays.asList(student2)); } /** * 通过for each 方法访问集合元素 * @param args */ public void testForEach() { System.out.println('有如下学生(通过for each):'); for(Object obj:students){ Student st = (Student)obj; System.out.println('学生:' + st.id + ':' + st.name); } } public static void main(String[] args){ SetTest st = new SetTest(); st.testAdd(); st.testForEach(); PD pd = new PD('1','张老师'); System.out.println('请:' + pd.name + '选择小组成员!'); //创建一个 Scanner 对象,用来接收从键盘输入的课程 ID Scanner console = new Scanner(System.in); for(int i = 0;i < 3; i++){ System.out.println('请输入学生 ID'); String studentID = console.next(); for(Student s:st.students){ if(s.id.equals(studentID)){ pd.students.add(s); } } } st.testForEachForSer(pd); } //打印输出,老师所选的学生!Set里遍历元素只能用foreach 和 iterator //不能使用 get() 方法,因为它是无序的,不能想 List 一样查询具体索引的元素 public void testForEachForSer(PD pd){ for(Student s: pd.students) { System.out.println('选择了学生:' + s.id + ':' + s.name); } } }
同学们上面的代码看得懂吗?多在 Eclipse 上写一写,然后学会举一反三哦。
3、HashMap 类
HashMap 是 Map 的一个重要实现类,也是最常用的,基于哈希表实现。HashMap 中的 Entry 对象那个是无序排列的,Key 值和 value 值都可以为 null,但是一个 HashMap 只能一个 key 值为 null 的映射(key 值不可重复)下面我们通过代码来学习 Map 中的方法吧。同学们都有过选课经历吧,我们就用 Map 来管理课程吧。
创建一个 Course 类:
package com.shiyanlou.test_collection_demo; public class Course { public String id; public String name; public Course(String id, String name){ this.id = id; this.name = name; } }
创建一个 MapTest 类:
package com.shiyanlou.test_collection_demo; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Scanner; import java.util.Set; public class MapTest { /** * 用来承装课程类型对象 */ public Map<String, Course> courses; /** * 在构造器中初始化 courses 属性 * @param args */ public MapTest() { this.courses = new HashMap<String, Course>(); } /** * 测试添加:输入课程 ID,判断是否被占用 * 若未被占用,输入课程名称,创建新课程对象 * 并且添加到 courses 中 * @param args */ public void testPut() { //创建一个 Scanner 对象,用来获取输入的课程 ID 和名称 Scanner console = new Scanner(System.in); for(int i = 0; i < 3; i++) { System.out.println('请输入课程 ID:'); String ID = console.next(); //判断该 ID 是否被占用 Course cr = courses.get(ID); if(cr == null){ //提示输入课程名称 System.out.println('请输入课程名称:'); String name = console.next(); //创建新的课程对象 Course newCourse = new Course(ID,name); //通过调用 courses 的 put 方法,添加 ID-课程映射 courses.put(ID, newCourse); System.out.println('成功添加课程:' + courses.get(ID).name); } else { System.out.println('该课程 ID 已被占用'); continue; } } } /** * 测试 Map 的 keySet 方法 * @param args */ public void testKeySet() { //通过 keySet 方法,返回 Map 中的所有键的 Set 集合 Set<String> keySet = courses.keySet(); //遍历 keySet,取得每一个键,在调用 get 方法取得每个键对应的 value for(String crID: keySet) { Course cr = courses.get(crID); if(cr != null){ System.out.println('课程:' + cr.name); } } } /** * 测试删除 Map 中的映射 * @param args */ public void testRemove() { //获取从键盘输入的待删除课程 ID 字符串 Scanner console = new Scanner(System.in); while(true){ //提示输出待删除的课程 ID System.out.println('请输入要删除的课程 ID!'); String ID = console.next(); //判断该 ID 是否对应的课程对象 Course cr = courses.get(ID); if(cr == null) { //提示输入的 ID 并不存在 System.out.println('该 ID 不存在!'); continue; } courses.remove(ID); System.out.println('成功删除课程' + cr.name); break; } } /** * 通过 entrySet 方法来遍历 Map * @param args */ public void testEntrySet() { //通过 entrySet 方法,返回 Map 中的所有键值对 Set<Entry<String,Course>> entrySet = courses.entrySet(); for(Entry<String,Course> entry: entrySet) { System.out.println('取得键:' + entry.getKey()); System.out.println('对应的值为:' + entry.getValue().name); } } /** * 利用 put 方法修改Map 中的已有映射 * @param args */ public void testModify(){ //提示输入要修改的课程 ID System.out.println('请输入要修改的课程 ID:'); //创建一个 Scanner 对象,去获取从键盘上输入的课程 ID 字符串 Scanner console = new Scanner(System.in); while(true) { //取得从键盘输入的课程 ID String crID = console.next(); //从 courses 中查找该课程 ID 对应的对象 Course course = courses.get(crID); if(course == null) { System.out.println('该 ID 不存在!请重新输入!'); continue; } //提示当前对应的课程对象的名称 System.out.println('当前该课程 ID,所对应的课程为:' + course.name); //提示输入新的课程名称,来修改已有的映射 System.out.println('请输入新的课程名称:'); String name = console.next(); Course newCourse = new Course(crID,name); courses.put(crID, newCourse); System.out.println('修改成功!'); break; } } public static void main(String[] args) { MapTest mt = new MapTest(); mt.testPut(); mt.testKeySet(); mt.testRemove(); mt.testModify(); mt.testEntrySet(); } }
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树
- [原创]java局域网聊天系统