Java中的集合,
Java中的集合,
Java中的集合
集合就像是一个购物车,可以将购买的所有商品的存放在一个统一的购物车中
集合的概念
现实生活: 很多的事物凑在一起
数学中的集合: 具有共同属性的事物的总体
Java中的集合类: 是一种工具类,是一种容器,里面可以存储任意数量的相同属性的类。
集合的作用
在类的内部对数据进行组织
简单快速的搜索大数量的条目
有的集合借口,提供了一系列排列有序的元素,并且可以在序列中快速地插入或者删除元素
有的集合接口,提供了映射关系,可以通过关键字(key)去快速查找到对应的唯一对象,而这 个关键字可以是任意类型
两个集合框架
Collection
- List
- Queue
- Set
List、Queue、Set的区别:
List和Queue中的元素是有序排列的
Set中的元素是无序排列的
在Collection中存储的是一个一个独立的对象
Map
在Map中会以<Key,Value>,也就是两个对象形成一个映射的关系的方式去存储数据,这有点像C#中的Diectory类型。
Collection 接口、子接口及其实现类
JDK API
List接口及其实现类 --- ArrayList
- List中的元素可以是重复的并且是有序排列的,被称为序列
- List可以精确的控制每个元素的插入位置,或删除某个位置元素
- ArrayList --- 数组序列,是List的一个重要实现类
- ArrayList的底层是由数组实现的
实现功能 --- 模拟学生选课功能
- 选择课程(往集合中添加课程)
- 删除所选的某门课程(删除集合中的元素)
- 查看所选课程
- 修改所选课程
//: Course.java
package com.faraj.collection;
public class Course {
public String name;
public String id;
public Course(String id, String name) {
this.id = id;
this.name = name;
}
}
创建课程类Course.java 由于是学习,类中的属性就用了public实际应用应该使用private修饰,然后添加getName; setName; getId; SetId方法;
//: Student.java
package com.faraj.collection;
import java.util.HashSet;
import java.util.Set;
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>();
}
}
创建学生类Student.java
//: ListTest.java
package com.faraj.collection;
import java.util.*;
public class ListTest {
public List<Course> coursesToSelect;
public ListTest() {
this.coursesToSelect = new ArrayList<Course>();
}
/**
* 给courseToSelect添加元素
*/
public void addTest() {
Course cr1 = new Course("1", "数据库系统概论");
coursesToSelect.add(cr1);
Course temp = coursesToSelect.get(0);
System.out.println("已添加课程: " + temp.id + "-" + temp.name);
coursesToSelect.add(0, new Course("2", "数据结构"));
Course temp2 = coursesToSelect.get(0);
System.out.println("已添加课程: " + temp2.id + "-" + temp2.name);
coursesToSelect.add(0, new Course("2", "数据结构"));
Course[] courses = new Course[]{
new Course("3", "线性代数"),
new Course("4", "ASP网页设计")
};
coursesToSelect.addAll(Arrays.asList(courses));
System.out.println("已添加课程: " + coursesToSelect.get(2).id + "-" +
coursesToSelect.get(2).name);
System.out.println("已添加课程: " + coursesToSelect.get(3).id + "-" +
coursesToSelect.get(3).name);
coursesToSelect.addAll(2, Arrays.asList(
new Course("5", "面向对象编程"),
new Course("6", "汇编语言")));
System.out.println("已添加课程: " + coursesToSelect.get(2).id + "-" +
coursesToSelect.get(2).name);
System.out.println("已添加课程: " + coursesToSelect.get(3).id + "-" +
coursesToSelect.get(3).name);
}
/**
* 获取集合中的所有元素
*/
public void getTest() {
for (int i = 0; i < coursesToSelect.size(); i++) {
System.out.println("课程:" + coursesToSelect.get(i).id + " - " +
coursesToSelect.get(i).name);
}
}
/**
* 通过迭代器遍历List
*/
public void iteratorTest() {
Iterator<Course> it = coursesToSelect.iterator();
int i = 1;
while (it.hasNext()) {
Course cr = it.next();
System.out.println("课程" + i++ + ":" + cr.id + "-" + cr.name);
}
}
/**
* 使用foreach方式循环获得list中的所有元素
*/
public void foreachTest() {
int i = 1;
for (Course cr : coursesToSelect) {
System.out.println("课程" + i++ + ":" + cr.id + "-" + cr.name);
}
}
/**
* 修改List中的元素
*/
public void modifyTest() {
coursesToSelect.set(1, new Course("7", "Java语言设计"));
}
/**
* 删除List中的元素
*/
public void removeTest(){
coursesToSelect.remove(0);
}
public static void main(String[] args) {
ListTest lt = new ListTest();
lt.addTest();
// lt.getTest();
// lt.iteratorTest();
lt.modifyTest();
lt.removeTest();
lt.foreachTest();
}
}
创建备选课程类ListTest.java
package com.faraj.collection;
import java.util.*;
public class SetTest {
public List<Course> coursesToSelect;
public SetTest() {
coursesToSelect = new ArrayList<Course>();
}
public void add() {
coursesToSelect.addAll(
Arrays.asList(
new Course("1", "数据库系统概论"),
new Course("2", "C语言基础"),
new Course("3", "Python语言实践"),
new Course("4", "基础算法实现"),
new Course("5", "汇编语言"),
new Course("6", "Linux基础"),
new Course("7", "面向对象编程"))
);
}
public void getAll() {
for (Course c : coursesToSelect) {
System.out.println(c.id + "--" + c.name);
}
}
public static void main(String[] args) {
SetTest st = new SetTest();
st.add();
st.getAll();
Student stu = new Student("1", "Faraj");
Scanner sca = new Scanner(System.in);
System.out.println("Welcome Stu. " + stu.name + "to select courses. You should and only can select 3 course.");
int num = 1;
for (int i = 0; i < 3; i++) {
System.out.println("Please choose NO. " + num + " course's ID");
num ++;
String input = sca.next();
for (Course cor : st.coursesToSelect) {
if (cor.id.equals(input)) {
stu.courses.add(cor);
}
}
}
System.out.println("你选择了:");
for (Course stuC : stu.courses) {
System.out.println(stuC.id + " - " + stuC.name);
}
}
}
Map和HashMap
Map接口
- Map提供了一种映射关系,其中的元素是以键值()对的形式存储的,能够实现根据key查找value
- Map中的键值对是以Entry类型的对象实例形式存在
- key不可重复,但是value值可以重复
- 每个key只能映射一个值
- Map 支持范性,Map<K,V>
HashMap类
- HashMap是Map的一个重要实现类,也是最常用的,基于哈希表实现
- HashMap中的Entry对象是无序排列的
- Key和Value的值都可以为null, 但是一个HashMap中只能有一个Key值为null的映射(Key值不可重复)
案例:
功能说明: 通过Map<String,Student>进行学生信息管理
其中key为学生的ID,value为学生对象
通过键盘输入学生信息
对集合中的学生信息进行增删改查
创建MapTest.java
//: MapTest.java
package com.faraj.collection;
import java.util.*;
public class MapTest {
public Map<String, Student> students;
public MapTest() {
students = new HashMap<>();
}
/**
* 通过put方法在Map中添加entry(键值对)
*/
public void putTest() {
Scanner scan = new Scanner(System.in);
while (true) {
System.out.println("请输入学生ID");
String id = scan.next();
int nextInput;
if (students.get(id) == null) {
System.out.println("请输入学生的姓名");
students.put(id, new Student(id, scan.next()));
System.out.println("是否继续添加? 1继续 2退出");
nextInput = scan.nextInt();
if (nextInput != 1) {
if (nextInput == 2) break;
}
} else {
System.out.println("该ID已存在");
System.out.println("是否重新添加 1是 2退出");
while (true) {
try {
nextInput = scan.nextInt();
break;
} catch (InputMismatchException e) {
System.out.println("你输入的内容不合法,请重新输入");
}
}
if (nextInput != 1) {
if (nextInput == 2) break;
}
}
}
}
/**
* 通过keySet取得遍历students
*/
public void keySetTest() {
Set<String> keys = students.keySet();
System.out.println("现已添加学生人数:" + keys.size());
for (String stuId : keys) {
System.out.println("学生(" + stuId + ")" + students.get(stuId).name);
}
}
/**
* 使用entrySet遍历students
*/
public void entrySetTest() {
Set<Map.Entry<String, Student>> entries = students.entrySet();
System.out.println("学生总数:" + entries.size());
for (Map.Entry<String, Student> entry : entries) {
System.out.println(entry.getKey() + " - " + entry.getValue().name);
}
}
/**
* 从Map中删除学生
*/
public void removeTest() {
Scanner scan = new Scanner(System.in);
while (true) {
System.out.println("请输入要删除的学生ID");
String id = scan.next();
if (students.get(id) == null) {
System.out.println("找不到该学生ID");
System.out.println("重新输入请输入1,退出应输入2");
int next = scan.nextInt();
if (next != 1) {
if (next == 2) {
break;
}
}
} else {
System.out.println("学生(" + id + ")" + students.get(id).name + " 已被删除");
students.remove(id);
System.out.println("重新输入请输入1,退出应输入2");
int next = scan.nextInt();
if (next != 1) {
if (next == 2) {
break;
}
}
}
}
}
/**
* 通过Put方法更改学生姓名
*/
public void modifyTest() {
Scanner scan = new Scanner(System.in);
while (true) {
System.out.println("请输入要修改的学生的ID");
String stuId = scan.next();
Student stu = students.get(stuId);
if (stu == null) {
System.out.println("该ID的学生不存在,请重新输入");
continue;
}
System.out.println("当前学生(" + stuId + ")" + " - " + stu.name + ", 请输入修改后的名字");
String newName = scan.next();
Student newStu = new Student(stuId,newName);
students.put(stuId,newStu);
break;
}
}
public static void main(String[] args) {
MapTest mt = new MapTest();
mt.putTest();
mt.keySetTest();
mt.modifyTest();
mt.entrySetTest();
}
}
判断coursesToSelect(List)中是否存在课程
在Course.java中重写equals方法
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Course)){
return false;
}
Course cour = (Course)obj;
if (cour.name == null){
return this.name == null;
}else{
return this.name.equals(cour.name);
}
}
在SetTest.java类中添加以下方法
public void containsTest() {
System.out.println("请输入你要查找的名称");
Course inputCourse = new Course();
inputCourse.name = scan.next();
if (coursesToSelect.contains(inputCourse))
System.out.println("包含《" + inputCourse.name + "》");
else System.out.println("不包含《" + inputCourse.name + "》");
}
在SetTest.java的main方法中测试该方法
st.containsTest();
另外在List中还有一个containsAll()方法,其用法与contains差不多,就是传入的是一个比较的对象集合
判断Set中是否存在课程
将之前SetTest.java中的部分代码提取成一个单独的方法
public void createStuAndSelectCourse(){
Student stu = new Student("1", "Faraj");
System.out.println("Welcome Stu. " + stu.name + "to select courses. You should and only can select 3 course.");
int num = 1;
for (int i = 0; i < 3; i++) {
System.out.println("Please choose NO. " + num + " course's ID");
num++;
String input = scan.next();
for (Course cor : coursesToSelect) {
if (cor.id.equals(input)) {
stu.courses.add(cor);
}
}
}
System.out.println("你选择了:");
for (Course stuC : stu.courses) {
System.out.println(stuC.id + " - " + stuC.name);
}
}
在该文件中创建一下方法
public void setContainsTest() {
System.out.println("请输入学生选则的课程名称");
String name = scan.next();
Course inputCourse = new Course();
inputCourse.name = name;
if (student.courses.contains(inputCourse)) {
System.out.println("该学生选择了《" + inputCourse.name + "》");
} else {
System.out.println("该学生并没有选择《" + inputCourse.name + "》");
}
}
在main方法中调用新创建的两个方法
st.createStuAndSelectCourse();
st.setContainsTest();
运行程序发现HashSet中的contains方法告诉我们并没有包含课程
不用担心,这不是因为我们的代码写错了,而是……
HashSet的contains方法的实现机制
在Object这个根类中除了定义了上面通过Course类重写的equals()方法,还定义了一个**hashCode()**方法,这个方法返回的是对象的哈希码的值,当我们在调用HashSet的contains()方法的时候,其实先调用每个元素的hashCode获取它们的哈希码,如果哈希码相等的情况下,才会调用equals方法来判断是否相等,这有当这两个方法返回的值都是true的时候,contains()方法才会认定这个HashSet包含某个元素。
graph LR co>HashSet.contains] ==> hc{.hashCode} hc{比较.hashCode} -.相等.-> eq(.equals) hc{比较.hashCode} -. 不相等 .-> false[false] eq(.equals) -.true.-> True[True] eq(.equals) -.false.-> false[false] style co fill:#FFBB4A,color:white,stroke-width:0px style hc fill:#3FBA69,color:white,stroke-width:0px style eq fill:#3FBA69,color:white,stroke-width:0px style True fill:#069BF9,color:white,stroke-width:0px style false fill:#EF3C41,color:white,stroke-width:0px在Course类中添加hashCode方法的重写
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
然后重新启动程序,就能看到程序正常运行了
相关文章
- 暂无相关文章
用户点评