Java 之集合框架 上
Posted 风中的簌雨
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 之集合框架 上相关的知识,希望对你有一定的参考价值。
Java 中的集合框架
如果一个类中存在很多相同类型的属性。
例如:学生类
学生可以选课,因此存在很多课程类型的属性。但是每个学生选择的课程的种类和数量是不一样的。
如果将每一个课程类型的属性都列到课程类中,这样就很难定义学生类了。
这时我们可以利用容器,把所有的课程类型的属性都加入到容器中,再将这个容器整体作为学生类的一个属性
上面所说的容器就是Java中的集合。
集合的概念:
现实生活中:很多的事物凑在一起。例如 超市中的购物车是商品的集合、军队是军人的集合
数学中的集合:具有共同属性的事物的总体。例如:有理数 和 整数
Java中的集合类:是一种工具类,就像是一个容器,储存任意数量的有共同属性的对象。
集合的作用:
1 在集合的内部,对数据进行组织
2 简单而快速的搜索大量的条目
3 有的集合接口,提供一系列排列有序的元素,并且可以在序列中间快速的插入或者删除有关的元素。
4 有的集合接口,提供映射关系,可以通过关键字(key)去快速查找到对应关系的唯一对象,可这个关键字可以使任意类型。
集合与数组的对比:
数组的长度或者说是容量是固定的,如果数组的长度不够用了,我们需要新建一个然后将原数组的元素复制进去,这样会很麻烦
集合的长度(容量)可以在使用过程中动态扩展
数组之能通过下标访问元素,类型固定,而有的集合可以通过任意类型查找所映射的具体对象
Java中的集合体系分为(两类):
Collection:
下面有三个接口 List、 Queue、 Set
List和Queue中存的元素是有序的,可以重复
Set中存的元素无序且不可重复
List下有一个常用的类ArraysList(数组序列)
Queue下有一个常用的类LinkedList(链表)List接口同样可以使用
Set下也有一个常用的类HashSet类
Map:
常用的有一个常用的实现类HashMap
PS~:
Collection类中存储的为一个一个独立的对象(一个一个的单身汉)
Map类中会将<Key,Value>(Entry键值对)作为一个映射对象存储其中(一对一对的情侣)
Collection接口:
是List、Set、Queue接口的父接口
定义了可用于操作List、Set、Queue的方法(增删改查)
(具体方法可以参考JDK的API文档)
因为文件较大无法上传,想要了解的朋友可以联系我,也可以直接上网自行百度
List接口及其实现类——ArraysList
List是元素有序并且可以重复的集合,被称为序列
List可以精确的控制每一个元素的插入位置,或者删除某一个位置元素
ArraysList--数组序列,是List的一个重要实现类
ArraysList的底层是由数组实现的
下面有一个具体的实例来应用一下List
实现功能——模拟学生选课功能
1 选择课程(往集合中添加课程)
2 删除所选的某门课程(删除集合中的元素)
3 查看所选的课程
4 修改所选的课程
学生选课——创建学生类和课程类
import java.util.Set; //这两个包不要忘记添加哦 import java.util.HashSet; // 学生类 public class Student { public String id; public String name; public Set courses; // 学生类的构造函数(含参构造器) public Student(String id, String name){ this.id = id; this.name = name; // 初始化courses属性 Set是一个接口不能直接初始化 // 所以这里用HashSet初始化 this.courses = new HashSet(); } } // 课程类 public class Course { public String id; public String name; // 课程类的构造函数(含参构造器) public Course(String id ,String name){ this.id = id; this.name = name; } }
学生选课——添加课程
首先要将备选课程添加至List容器中(创建ListTest类)
3 import java.sql.Array; 4 import java.util.ArrayList; 5 import java.util.Arrays; 6 import java.util.Iterator; 7 import java.util.List; 8 9 public class ListTest { 10 // 备选课程 11 public List coursesToSelect; 12 13 // ListTest类的构造方法 14 public ListTest(){ 15 // List是一个接口不能直接初始化 使用List接口下的ArrayList类 16 this.coursesToSelect = new ArrayList(); 17 } 18 19 // 用于往coursesToSelect中添加备选课程 20 public void testAdd(){ 21 // 创建一个课程对象,并通过调用add方法,添加到备选课程List中 22 Course cr1 = new Course("1","数据结构"); 23 coursesToSelect.add(cr1); 24 /* 通过List的get方法取出元素,验证课程是否添加成功 25 * 由于对象存入集合都变成里object类型,取出时需要类型转换 26 * 由于这是添加的第一个课程信息所以下标为0 27 */ 28 Course temp = (Course) coursesToSelect.get(0); 29 System.out.println("添加了课程:" + temp.id + temp.name ); 30 31 32 33 /* 34 * List中还重载了另一个add方法 该方法不仅可以添加新元素, 35 * 而且可以指定添加的位置 36 */ 37 Course cr2 = new Course("2","C语言"); 38 coursesToSelect.add(0,cr2); // 指定添加位置为0,原位置上的元素被挤下去 39 Course temp2 = (Course) coursesToSelect.get(0); // 类型强转 40 System.out.println("添加了课程:" + temp2.id + temp2.name ); 41 42 43 /* 44 * 在添加课程过程中,如果传递的位置参数大于现在的长度时(或者数组下标小于0) 45 * 会报(IndexOutOfBoundsException)异常 46 */ 47 // Course cr3 = new Course("3","概率论"); 48 // coursesToSelect.add(4, cr3); 49 // Course temp3 = (Course) coursesToSelect.get(0); 50 // System.out.println("添加了课程" + temp3.id + temp3.name); 51 52 53 /* 54 * 除了add方法 还有另外两种方法可以实现往List中添加课程 55 * addAll方法 首先将course数组通过Arrays的asList方法转变为List 56 * 1 直接利用addAll添加课程 2 通过传递一个位置参数将课程添加至指定位置 57 */ 58 Course[] course = {new Course("4","离散数学"), new Course("5","汇编语言")}; 59 coursesToSelect.addAll(Arrays.asList(course)); 60 Course temp4 = (Course) coursesToSelect.get(2); 61 Course temp5 = (Course) coursesToSelect.get(3); 62 System.out.println("添加了两门课程:" + temp4.id + temp4.name + 63 temp5.id + temp5.name); 64 65 Course[] course2 = {new Course("6","高等数学"), new Course("6","大学英语")}; 66 coursesToSelect.addAll(2,Arrays.asList(course2)); 67 Course temp6 = (Course) coursesToSelect.get(2); 68 Course temp7 = (Course) coursesToSelect.get(3); 69 System.out.println("添加了两门课程:" + temp6.id + temp6.name + 70 temp7.id + temp7.name); 71 72 73 // List中的元素可以重复 以下是代码演示 74 // coursesToSelect.add(cr1); 75 // Course temp0 = (Course) coursesToSelect.get(6); 76 // System.out.println("添加了课程:" + temp0.id + temp0.name ); 77 78 } 79 80 81 // 取得List中的元素的方法 82 public void testGet(){ 83 System.out.println(); 84 int size = coursesToSelect.size(); // 取得List中的元素个数 85 System.out.println("有如下课程待选:"); 86 for (int i = 0; i < size; i ++){ 87 Course cr = (Course) coursesToSelect.get(i); 88 System.out.println("课程:"+cr.id + cr.name); 89 } 90 } 91 92 93 /* 94 * 通过迭代器来遍历List 95 * 迭代器只用来遍历集合中元素,本身不具备存储功能 96 * 还有另一种写法(简便版) ForEach 97 */ 98 public void testIterator(){ 99 System.out.println(); 100 // 通过集合的iterator方法,取得迭代器的实例 101 Iterator it = coursesToSelect.iterator(); 102 System.out.println("有如下课程待选(通过迭代器访问):"); 103 while (it.hasNext()){ 104 Course cr = (Course) it.next(); 105 System.out.println("课程:"+cr.id + cr.name); 106 } 107 } 108 // 通过for each 方法访问集合元素 109 public void testForEach(){ 110 System.out.println(); 111 System.out.println("有如下课程可选(通过for each访问):"); 112 for (Object obj : coursesToSelect){ 113 Course cr = (Course)obj; 114 System.out.println("课程:" + cr.id + cr.name); 115 } 116 } 117 118 /* 119 * 修改List中的元素 120 * 利用List中的Set方法修改元素值 121 * set中有两个参数 位置参数 更改的值 122 */ 123 public void testModify(){ 124 coursesToSelect.set(4, new Course("7","毛概")); 125 } 126 127 128 // 删除List中的元素 有两种方法法 129 public void testRemove (){ 130 System.out.println(); 131 Course cr = (Course) coursesToSelect.get(4); 132 System.out.println("我是课程:"+cr.id + cr.name+"我即将被删除"); 133 coursesToSelect.remove(cr); 134 // 也可以直接删除指定位置上的元素 效果一样 135 // coursesToSelect.remove(4); 136 System.out.println("成功删除课程!"); 137 testForEach(); 138 139 // System.out.println("即将删除4位置和5位置上的元素!"); 140 // Course[] courses = {(Course) coursesToSelect.get(3),(Course) coursesToSelect.get(4)}; 141 // coursesToSelect.removeAll(Arrays.asList(courses)); 142 // System.out.println("成功删除课程!"); 143 // testForEach(); 144 } 145 146 147 /* 148 * 前面我们所添加的都是一些正常的课程信息(课程id,课程name) 149 * 但是当我们添加了一些“不正常的信息”时 会怎么样嘞? 150 * 下面我们来试验一下: 151 * 往List中添加一些奇怪的东西 152 * 运行之后你会发现 程序并没有add成功 153 * 并且抛出了一个 ClassCastException异常(String类型不能被强转为course类型) 154 * 155 * 156 * 有木有办法控制我们往某一个集合或者List中添加元素的类型嘞? 157 * YES 这里我们可以利用 “泛型” 关于泛型的概念在下面会有介绍 158 */ 159 160 // public void testType(){ 161 // System.out.println("能否往List中添加一些奇怪的东西呢?"); 162 // coursesToSelect.add("我不是课程 我只是一个字符串!"); 163 // } 164 165 166 public static void main (String[] args){ 167 // 创建ListTest 对象的实例 168 ListTest lt = new ListTest(); 169 lt.testAdd(); 170 lt.testGet(); 171 lt.testIterator(); 172 lt.testForEach(); 173 lt.testModify(); 174 lt.testForEach(); 175 lt.testRemove(); 176 //lt.testType(); 177 lt.testForEach(); 178 } 179 180 }
添加了课程:1数据结构
添加了课程:2C语言
添加了两门课程:4离散数学5汇编语言
添加了两门课程:6高等数学6大学英语
有如下课程待选:
课程:2C语言
课程:1数据结构
课程:6高等数学
课程:6大学英语
课程:4离散数学
课程:5汇编语言
有如下课程待选(通过迭代器访问):
课程:2C语言
课程:1数据结构
课程:6高等数学
课程:6大学英语
课程:4离散数学
课程:5汇编语言
有如下课程可选(通过for each访问):
课程:2C语言
课程:1数据结构
课程:6高等数学
课程:6大学英语
课程:4离散数学
课程:5汇编语言
有如下课程可选(通过for each访问):
课程:2C语言
课程:1数据结构
课程:6高等数学
课程:6大学英语
课程:7毛概
课程:5汇编语言
我是课程:7毛概我即将被删除
成功删除课程!
有如下课程可选(通过for each访问):
课程:2C语言
课程:1数据结构
课程:6高等数学
课程:6大学英语
课程:5汇编语言
有如下课程可选(通过for each访问):
课程:2C语言
课程:1数据结构
课程:6高等数学
课程:6大学英语
课程:5汇编语言
泛型:
用于控制往某个集合或者List中添加元素的类型
集合中的元素,可以是任意类型的对象(对象的引用)
如果把某一个对象放入到集合,则会忽略他的类型而把它当做Object处理
泛型则是规定了某个集合只可以存放特定类型的对象,并且会在编译过程中进行类型检查。可以直接按指定类型获取集合元素
注意:
泛型集合中的限定类型不能使用基本数据类型。
可以通过使用 包装类 限定允许存入的基本数据类型。
1 /* 2 * ChildCourse 继承Course类型 而Course中我们定义了一个含参构造器 3 * 所以编译器就不会再自动添加一个隐式的无参构造器 4 * 但是在Course的子类(该类)中必须要调用父类的隐式构造器 5 * 所以这里会提示错误 6 * 这是我们只需要再course类中手动添加一个无参构造器即可 7 */ 8 public class ChildCourse extends Course { 9 10 /* 11 * ChildCourse无需再添加任何属性 12 * 所有的属性均继承Course类型的属性即可 13 */ 14 } 15 16 import java.util.ArrayList; 17 import java.util.List; 18 19 public class TestGeneric { 20 21 // 带有泛型——Course,的List类型属性 22 public List<Course> courses; 23 24 public TestGeneric(){ // 因为指定了泛型 所以这里要加上<Course> 25 this.courses = new ArrayList<Course>(); // 后面的圆括号表示调用了构造方法 26 } 27 28 // 测试添加 29 public void testAdd(){ 30 Course cr1 = new Course("1","大学语文"); 31 courses.add(cr1); 32 /* 33 * 当添加的信息不正确时 编译器会直接报错 34 * 泛型集合中,不能添加泛型规定的类型及其子类型以外的对象,否则会报错 35 */ 36 //courses.add("能否添加一些奇怪的东西?"); 37 Course cr2 = new Course("2","Java基础教程"); 38 courses.add(cr2); 39 } 40 41 // 测试循环遍历 42 public void testForEach(){ 43 // 这里的course在编译的时候已经规定了泛型,所以这里不用再把当做Object类型转换 44 for (Course cr:courses){ 45 System.out.println(cr.id + cr.name); 46 47 } 48 } 49 50 // 测试泛型集合可以添加泛型的子类型的塑像实例 51 public void testChild (){ 52 ChildCourse ccr = new ChildCourse(); 53 ccr.id = "3"; 54 ccr.name = "我是子类型的课程对象实例~~"; 55 courses.add(ccr); 56 } 57 58 /* 59 * 注意: 60 * 泛型集合中的限定类型不能使用基本数据类型。 61 * 可以通过使用 包装类 限定允许存入的基本数据类型。 62 */ 63 public void testBasicType(){ 64 // 这里如果写成int的话编译器会报错,所以要用Integer 65 List<Integer> list = new ArrayList<Integer>(); 66 list.add(1); // 这里的1(基本类型) 被强制转换成了int的包装类Integer,然后被加入到list中 67 System.out.println("基本类型必须使用包装类作为泛型" + list.get(0)); 68 } 69 70 71 public static void main(String[] args) { 72 73 TestGeneric tg = new TestGeneric(); 74 tg.testAdd(); 75 tg.testForEach(); 76 77 tg.testChild(); 78 tg.testForEach(); 79 80 tg.testBasicType(); 81 } 82 83 }
1大学语文 2Java基础教程 1大学语文 2Java基础教程 3我是子类型的课程对象实例~~ 基本类型必须使用包装类作为泛型1
PS~ 如有手误 欢迎指出
以上是关于Java 之集合框架 上的主要内容,如果未能解决你的问题,请参考以下文章