Java 之集合框架 上(9)
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类)
import java.sql.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List; public class ListTest {
// 备选课程
public List coursesToSelect; // ListTest类的构造方法
public ListTest(){
// List是一个接口不能直接初始化 使用List接口下的ArrayList类
this.coursesToSelect = new ArrayList();
} // 用于往coursesToSelect中添加备选课程
public void testAdd(){
// 创建一个课程对象,并通过调用add方法,添加到备选课程List中
Course cr1 = new Course("1","数据结构");
coursesToSelect.add(cr1);
/* 通过List的get方法取出元素,验证课程是否添加成功
* 由于对象存入集合都变成里object类型,取出时需要类型转换
* 由于这是添加的第一个课程信息所以下标为0
*/
Course temp = (Course) coursesToSelect.get(0);
System.out.println("添加了课程:" + temp.id + temp.name ); /*
* List中还重载了另一个add方法 该方法不仅可以添加新元素,
* 而且可以指定添加的位置
*/
Course cr2 = new Course("2","C语言");
coursesToSelect.add(0,cr2); // 指定添加位置为0,原位置上的元素被挤下去
Course temp2 = (Course) coursesToSelect.get(0); // 类型强转
System.out.println("添加了课程:" + temp2.id + temp2.name ); /*
* 在添加课程过程中,如果传递的位置参数大于现在的长度时(或者数组下标小于0)
* 会报(IndexOutOfBoundsException)异常
*/
// Course cr3 = new Course("3","概率论");
// coursesToSelect.add(4, cr3);
// Course temp3 = (Course) coursesToSelect.get(0);
// System.out.println("添加了课程" + temp3.id + temp3.name); /*
* 除了add方法 还有另外两种方法可以实现往List中添加课程
* addAll方法 首先将course数组通过Arrays的asList方法转变为List
* 1 直接利用addAll添加课程 2 通过传递一个位置参数将课程添加至指定位置
*/
Course[] course = {new Course("4","离散数学"), new Course("5","汇编语言")};
coursesToSelect.addAll(Arrays.asList(course));
Course temp4 = (Course) coursesToSelect.get(2);
Course temp5 = (Course) coursesToSelect.get(3);
System.out.println("添加了两门课程:" + temp4.id + temp4.name +
temp5.id + temp5.name); Course[] course2 = {new Course("6","高等数学"), new Course("6","大学英语")};
coursesToSelect.addAll(2,Arrays.asList(course2));
Course temp6 = (Course) coursesToSelect.get(2);
Course temp7 = (Course) coursesToSelect.get(3);
System.out.println("添加了两门课程:" + temp6.id + temp6.name +
temp7.id + temp7.name); // List中的元素可以重复 以下是代码演示
// coursesToSelect.add(cr1);
// Course temp0 = (Course) coursesToSelect.get(6);
// System.out.println("添加了课程:" + temp0.id + temp0.name ); } // 取得List中的元素的方法
public void testGet(){
System.out.println();
int size = coursesToSelect.size(); // 取得List中的元素个数
System.out.println("有如下课程待选:");
for (int i = 0; i < size; i ++){
Course cr = (Course) coursesToSelect.get(i);
System.out.println("课程:"+cr.id + cr.name);
}
} /*
* 通过迭代器来遍历List
* 迭代器只用来遍历集合中元素,本身不具备存储功能
* 还有另一种写法(简便版) ForEach
*/
public void testIterator(){
System.out.println();
// 通过集合的iterator方法,取得迭代器的实例
Iterator it = coursesToSelect.iterator();
System.out.println("有如下课程待选(通过迭代器访问):");
while (it.hasNext()){
Course cr = (Course) it.next();
System.out.println("课程:"+cr.id + cr.name);
}
}
// 通过for each 方法访问集合元素
public void testForEach(){
System.out.println();
System.out.println("有如下课程可选(通过for each访问):");
for (Object obj : coursesToSelect){
Course cr = (Course)obj;
System.out.println("课程:" + cr.id + cr.name);
}
} /*
* 修改List中的元素
* 利用List中的Set方法修改元素值
* set中有两个参数 位置参数 更改的值
*/
public void testModify(){
coursesToSelect.set(4, new Course("7","毛概"));
} // 删除List中的元素 有两种方法法
public void testRemove (){
System.out.println();
Course cr = (Course) coursesToSelect.get(4);
System.out.println("我是课程:"+cr.id + cr.name+"我即将被删除");
coursesToSelect.remove(cr);
// 也可以直接删除指定位置上的元素 效果一样
// coursesToSelect.remove(4);
System.out.println("成功删除课程!");
testForEach(); // System.out.println("即将删除4位置和5位置上的元素!");
// Course[] courses = {(Course) coursesToSelect.get(3),(Course) coursesToSelect.get(4)};
// coursesToSelect.removeAll(Arrays.asList(courses));
// System.out.println("成功删除课程!");
// testForEach();
} /*
* 前面我们所添加的都是一些正常的课程信息(课程id,课程name)
* 但是当我们添加了一些“不正常的信息”时 会怎么样嘞?
* 下面我们来试验一下:
* 往List中添加一些奇怪的东西
* 运行之后你会发现 程序并没有add成功
* 并且抛出了一个 ClassCastException异常(String类型不能被强转为course类型)
*
*
* 有木有办法控制我们往某一个集合或者List中添加元素的类型嘞?
* YES 这里我们可以利用 “泛型” 关于泛型的概念在下面会有介绍
*/ // public void testType(){
// System.out.println("能否往List中添加一些奇怪的东西呢?");
// coursesToSelect.add("我不是课程 我只是一个字符串!");
// } public static void main (String[] args){
// 创建ListTest 对象的实例
ListTest lt = new ListTest();
lt.testAdd();
lt.testGet();
lt.testIterator();
lt.testForEach();
lt.testModify();
lt.testForEach();
lt.testRemove();
//lt.testType();
lt.testForEach();
} }
添加了课程: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汇编语言
Output
泛型:
用于控制往某个集合或者List中添加元素的类型
集合中的元素,可以是任意类型的对象(对象的引用)
如果把某一个对象放入到集合,则会忽略他的类型而把它当做Object处理
泛型则是规定了某个集合只可以存放特定类型的对象,并且会在编译过程中进行类型检查。可以直接按指定类型获取集合元素
注意:
泛型集合中的限定类型不能使用基本数据类型。
可以通过使用 包装类 限定允许存入的基本数据类型。
/*
* ChildCourse 继承Course类型 而Course中我们定义了一个含参构造器
* 所以编译器就不会再自动添加一个隐式的无参构造器
* 但是在Course的子类(该类)中必须要调用父类的隐式构造器
* 所以这里会提示错误
* 这是我们只需要再course类中手动添加一个无参构造器即可
*/
public class ChildCourse extends Course { /*
* ChildCourse无需再添加任何属性
* 所有的属性均继承Course类型的属性即可
*/
} import java.util.ArrayList;
import java.util.List; public class TestGeneric { // 带有泛型——Course,的List类型属性
public List<Course> courses; public TestGeneric(){ // 因为指定了泛型 所以这里要加上<Course>
this.courses = new ArrayList<Course>(); // 后面的圆括号表示调用了构造方法
} // 测试添加
public void testAdd(){
Course cr1 = new Course("1","大学语文");
courses.add(cr1);
/*
* 当添加的信息不正确时 编译器会直接报错
* 泛型集合中,不能添加泛型规定的类型及其子类型以外的对象,否则会报错
*/
//courses.add("能否添加一些奇怪的东西?");
Course cr2 = new Course("2","Java基础教程");
courses.add(cr2);
} // 测试循环遍历
public void testForEach(){
// 这里的course在编译的时候已经规定了泛型,所以这里不用再把当做Object类型转换
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(){
// 这里如果写成int的话编译器会报错,所以要用Integer
List<Integer> list = new ArrayList<Integer>();
list.add(1); // 这里的1(基本类型) 被强制转换成了int的包装类Integer,然后被加入到list中
System.out.println("基本类型必须使用包装类作为泛型" + list.get(0));
} public static void main(String[] args) { TestGeneric tg = new TestGeneric();
tg.testAdd();
tg.testForEach(); tg.testChild();
tg.testForEach(); tg.testBasicType();
} }
1大学语文
2Java基础教程
1大学语文
2Java基础教程
3我是子类型的课程对象实例~~
基本类型必须使用包装类作为泛型1
Output
学生选课——通过set集合管理课程
Set接口及其实现类——HashSet
Set是元素无序并且不可以不可以重复的集合,被称为集
HashSet——哈希集,是set的一个重要实现类
Set中没有提供像list中的set()方法(修改指定位置上的元素):list——有序 set——无序
下面通过实例来形象的说明一下吧
案例功能说明:
1 提供备选课程
2 创建学生对象,并给该学生添加三门课程(添加到学生的courses——set类型的属性中)
显示备选课程
循环三次,每次输入课程ID
往学生的courses属性中添加与输入的ID匹配的课程
输出学生选择的课程
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class SetTest { /*
* 在前面的student类中 我们定义了一个set类型的属性
* 在这里 我们需要将上面student类中的set属性加一个泛型
*/ public List<Course> coursesToSelect; public SetTest(){
coursesToSelect = new ArrayList<Course>(); } /*
* 这里我们可以小小的偷个懒,将刚才写过的testAdd直接复制过来
* 同时将所有多余的打印输出注释掉
*/
// 用于往coursesToSelect中添加备选课程
public void testAdd(){
// 创建一个课程对象,并通过调用add方法,添加到备选课程List中
Course cr1 = new Course("1","数据结构");
coursesToSelect.add(cr1);
/* 通过List的get方法取出元素,验证课程是否添加成功
* 由于对象存入集合都变成里object类型,取出时需要类型转换
* 由于这是添加的第一个课程信息所以下标为0
*/
Course temp = (Course) coursesToSelect.get(0);
//System.out.println("添加了课程:" + temp.id + temp.name ); /*
* List中还重载了另一个add方法 该方法不仅可以添加新元素,
* 而且可以指定添加的位置
*/
Course cr2 = new Course("2","C语言");
coursesToSelect.add(0,cr2); // 指定添加位置为0,原位置上的元素被挤下去
Course temp2 = (Course) coursesToSelect.get(0); // 类型强转
//System.out.println("添加了课程:" + temp2.id + temp2.name ); /*
* 在添加课程过程中,如果传递的位置参数大于现在的长度时(或者数组下标小于0)
* 会报(IndexOutOfBoundsException)异常
*/
// Course cr3 = new Course("3","概率论");
// coursesToSelect.add(4, cr3);
// Course temp3 = (Course) coursesToSelect.get(0);
// System.out.println("添加了课程" + temp3.id + temp3.name); /*
* 除了add方法 还有另外两种方法可以实现往List中添加课程
* addAll方法 首先将course数组通过Arrays的asList方法转变为List
* 1 直接利用addAll添加课程 2 通过传递一个位置参数将课程添加至指定位置
*/
Course[] course = {new Course("4","离散数学"), new Course("5","汇编语言")};
coursesToSelect.addAll(Arrays.asList(course));
Course temp4 = (Course) coursesToSelect.get(2);
Course temp5 = (Course) coursesToSelect.get(3);
//System.out.println("添加了两门课程:" + temp4.id + temp4.name +
// temp5.id + temp5.name); Course[] course2 = {new Course("6","高等数学"), new Course("6","大学英语")};
coursesToSelect.addAll(2,Arrays.asList(course2));
Course temp6 = (Course) coursesToSelect.get(2);
Course temp7 = (Course) coursesToSelect.get(3);
//System.out.println("添加了两门课程:" + temp6.id + temp6.name +
// temp7.id + temp7.name); // List中的元素可以重复 以下是代码演示
// coursesToSelect.add(cr1);
// Course temp0 = (Course) coursesToSelect.get(6);
// System.out.println("添加了课程:" + temp0.id + temp0.name ); } // 通过for each 方法访问集合元素
public void testForEach(){
System.out.println();
System.out.println("有如下课程可选(通过for each访问):");
for (Object obj : coursesToSelect){
Course cr = (Course)obj;
System.out.println("课程:" + cr.id + cr.name);
}
} public static void main(String[] args) { SetTest st = new SetTest();
st.testAdd();
st.testForEach(); // 创建一个学生对象
Student student = new Student("1","小明");
System.out.println("欢迎学生:"+ student.name + "选课");
// 创建一个Scanner ,用来接收从键盘输入的课程ID
Scanner console = new Scanner(System.in); /*
* 输入三个ID 选三门课
* 将每一个ID 跟coursesToSelect中的每一个课程对象比较
* 如果ID相等的情况下,就将该课程对象添加到小明的选课信息中
*/
for (int i = 0; i < 3; i ++){
System.out.println("请输入课程ID:");
String courseId = console.next();
for (Course cr:st.coursesToSelect){
if (cr.id.equals(courseId)){
student.courses.add(cr);
student.courses.add(cr); //验证set中元素不可重复
// set 中添加某个对象,无论添加多少次最终只会保留一个该对象(的引用)
}
}
}
st.testForEachForSet(student);
} public void testForEachForSet(Student student){ //验证set中元素不可重复
System.out.println("共选择了:" + student.courses.size() + "门课程"); /*
* 打印输出,学生所选的课程!
* 这里需要说明一点 循环遍历set中的元素 只能用佛reach方法或者
* iterator方法,而不能像list那样调用get()方法
* 这是因为set本身是无序的,所以不可能去查询指定位置上的元素
* 只能通过循环迭代出来 由于它是无序的所以每一次他的结果都是不太一样的
*/ for (Course cr:student.courses){
System.out.println("选择了课程:" + cr.id + cr.name); }
}
}
PS~ 如有手误 欢迎指出
Java 之集合框架 上(9)的更多相关文章
- java的集合框架最全详解
java的集合框架最全详解(图) 前言:数据结构对程序设计有着深远的影响,在面向过程的C语言中,数据库结构用struct来描述,而在面向对象的编程中,数据结构是用类来描述的,并且包含有对该数据结构操作 ...
- Java基础——集合框架
Java的集合框架是Java中很重要的一环,Java平台提供了一个全新的集合框架.“集合框架”主要由一组用来操作对象的接口组成.不同接口描述一组不同数据类型.Java平台的完整集合框架如下图所示: 上 ...
- Java面向对象 集合(上)
Java面向对象 集合(上) 知识概要: (1)体系概述 (2)共性方法 (3)迭代器 (4)list集合 (5)Set 集合 体系概述: 集 ...
- java的集合框架set 和map的深入理解
Java的集合框架之Map的用法详解 Map有两种比较常用的实现:HashMap 和 TreeMap. HashMap: HashMap 也是无序的,也是按照哈希编码来排序的,允许使用null 值和n ...
- Java 高级-集合框架
参考资料 参考 HashMap 类似 C++ 中的 STL 标准模板库,Java 也在 java.util 包中封装了一套常用数据结构及其算法,称为集合框架.所有的集合框架都包含如下内容: 接口:代表 ...
- java.util 集合框架集合
java的集合框架为程序提供了一种处理对象组的标准方式.设计了一系列标准泛型接口: ⑴Collection ()接口,扩展了Iterable接口,位于集合层次结构的顶部,因此所有的集合都实现Colle ...
- java的集合框架之一
java是一套很成熟的东西,很多商用的东西都喜欢用它,用的人多,稳定.不过一般也不怎么说起它,因为太常见了,私下里说,写java应用层得就像农民工,每一处都是搭积木,根据设计师的东西如何优雅地搭好积木 ...
- 浅谈Java的集合框架
浅谈Java的集合框架 一. 初识集合 重所周知,Java有四大集合框架群,Set.List.Queue和Map.四种集合的关注点不同,Set 关注事物的唯一性,List 关注事物的索引列表,Q ...
- Java 之 集合框架(JCF)
1.集合框架 a.框架:为了实现某一目的或功能,而预先提供的一系列封装好的.具有继承或实现关系的类与集合 b.集合:①定义:Java中对一些数据结构和算法进行封装,即封装(集合也是一种对象) ②特点: ...
随机推荐
- shiro原理及其运行流程介绍
shiro原理及其运行流程介绍 认证执行流程 1.通过ini配置文件创建securityManager 2.调用subject.login方法主体提交认证,提交的token 3.securityMan ...
- .Net Core 使用NLog记录日志到文件和数据库
NLog 记录日志是微软官方推荐使用. 接下来,通过配置日志记录到文件和Sql Server数据库. 第一步:首先添加包NLog.Config (可通过微软添加包命令Install-Package 包 ...
- 并发编程>>概念准备(一)
工于其善,必先利器 1.并发和并行的区别 并行:同一时间点执行多个任务(CPU多核或多个CPU同时执行多个任务) 并发:同一时间段内行多个任务(单核同时执行多个任务) 2.同步和异步的区别 同步:执行 ...
- 索引(Awakening!)
orz写个索引,方便日后复习和补充. 目前笔记还不是很多,而且写得比较烂,望各位到访的巨佬谅解. 大概可以算作一个归纳总结? ……没链接的还没开始写或者没写完,而且不知道什么时候才能写完(咕咕咕) 一 ...
- GeneXus学习笔记——创建一个知识库 哈哈哈哈!
终于想到写什么东西了(绝对不是因为懒 好吧 信我) 那么进入正题 我们写项目的时候 遇到一些问题啥的 总会听到大佬说:“这有什么难的 说到底不就是简单的增删改查么" 然后我们就会露出 Σ ...
- dubbo和zookeeper的关系
转载前言:网络上很多教程没有描述zookeeper和dubbo到底是什么关系.分别扮演了什么角色等信息,都是说一些似是而非的话,这里终于找到一篇文章,比较生动地描述了注册中心和微服务框架之间的关系,以 ...
- 造一个轮子然后安装到pypi上
之前写了一个爬虫的包,主要是根据自己写爬虫的情况总结一下. 因为每次都要重复写一些代码,所以提炼出来,类似一个框架的样子吧. 开始是放在自己的项目里引用,但如果换了一个项目,就得重新拷一遍,很麻烦. ...
- 在windows上添加cygwin右键
来了一台新机器,装环境的时候,突然想直接在右键使用cygwin. 查了一些教程,基本大同小异,也算是有用,先贴一个链接: https://blog.csdn.net/yang_hong_/articl ...
- 关于c#中”ref”和”out”关键字的一些理解
一. 综述(本文内容大部分来自网络,经本人整理而成,仅供学习参考,不免理解错误,欢迎批评指正) 在c#中,方法的参数传递有四种类型: (1) 传值参数(by value) 传值参数无需额外的修饰符.传 ...
- Linux 命令学习之cd
功能说明: cd 命令是 linux 最基本的命令语句,其他的命令都会依赖与 cd 命令.因此学好 cd 命令是必须的. 语 法:cd [目的目录] 补充说明:cd指令可让用户在不同的目录间切换,需要 ...