前言:本笔记中内容将继续完善笔记7,8中相关代码的功能,请先观看笔记7,8中相关代码,了解原理后再来学习本笔记中内容:
Java基础 学习笔记7
Java基础 学习笔记8
1.学生选课-判断List中课程是否存在
新建一个SetTest2类,里面很多代码和SetTest中是完全一致的:
package com.imooc.collection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class SetTest2 {
public List<Course> coursesToSelect; //带有泛型Course的List类型属性
public SetTest2() {
this.coursesToSelect = new ArrayList<Course>();
}
public void testAdd() { //用于往coursesToSelect中添加备选课程
//创建一个课程对象,并通过调用add方法,添加到备选课程List中
Course cr1 = new Course("1", "数据结构");
coursesToSelect.add(cr1);
Course cr2 = new Course("2", "C语言");
coursesToSelect.add(0, cr2);
Course[] course = {new Course("3", "离散数学"), new Course("4", "汇编语言")};
//add方法是用来添加单个的Course对象的,而addAll方法是将一个集合List里的所有元素都添加到courseToSelect集合里去的。
//Arrays.asList方法不是用来添加对象的,而是用来将Course数组转化为集合的。
coursesToSelect.addAll(Arrays.asList(course));
Course[] course2 = {new Course("5", "高等数学"), new Course("6", "大学英语")};
coursesToSelect.addAll(2, Arrays.asList(course2));
}
public void testListContains() {
//取得备选课程序列的第0个元素
Course course = coursesToSelect.get(0);
//打印输出查看coursesToSelect是否包含course对象
System.out.println("取得课程:" + course.name);
System.out.println("备选课程中是否包含课程:" + course.name + "," + coursesToSelect.contains(course));
//创建一个新的课程对象,ID和名称,与course对象完全一样
Course course2 = new Course(course.id, course.name);
System.out.println("新创建课程:" + course2.name);
System.out.println("备选课程中是否包含课程:" + course2.name + "," + coursesToSelect.contains(course2));
}
public static void main(String[] args) {
SetTest2 st = new SetTest2();
st.testAdd();
st.testListContains();
}
}
运行结果:
第二次比较返回结果是false的原因:
contains实现原理:所有类都是继承Object类,Object类中的equals方法比较的是对象的引用是否指向同一块内存地址-(对象实例化时,即给对象分配内存空间)。调用List的contains方法时,会遍历集合中的元素,调用每一个元素的equals方法将集合中的元素与传入的对象一一比较,如果相同就会返回true,而新建的这个course2很明显不是集合中的元素(地址不同),所以会返回false。
那么如果我们向根据内容判断是否存在某个课程(即相同的名称就会返回true),那么我们就需要重写equals方法。有同学可能会有疑问,你的笔记前面介绍的String类中的equals方法就是比较内容的啊,这是因为在Java中,String 、Math、还有Integer、Double等这些封装类重写了Object中的equals()方法,让它不再比较其对象在内存中的地址,而是比较对象中实际包含的整数的值,即比较的是内容。
在Course类中重写equals方法:
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;
}
}
再次执行SetTest2中的主函数,运行结果如下:
那么如果我们想让用户从键盘上输入一个课程名称,并查找集合中是否存在该课程,我们应该怎么办呢?其实很简单,只需要对上述代码做少部分修改即可:
package com.imooc.collection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class SetTest2 {
public List<Course> coursesToSelect; //带有泛型Course的List类型属性
private Scanner console;
public SetTest2() {
this.coursesToSelect = new ArrayList<Course>();
console = new Scanner(System.in);
}
public void testAdd() { //用于往coursesToSelect中添加备选课程
//创建一个课程对象,并通过调用add方法,添加到备选课程List中
Course cr1 = new Course("1", "数据结构");
coursesToSelect.add(cr1);
Course cr2 = new Course("2", "C语言");
coursesToSelect.add(0, cr2);
Course[] course = {new Course("3", "离散数学"), new Course("4", "汇编语言")};
//add方法是用来添加单个的Course对象的,而addAll方法是将一个集合List里的所有元素都添加到courseToSelect集合里去的。
//Arrays.asList方法不是用来添加对象的,而是用来将Course数组转化为集合的。
coursesToSelect.addAll(Arrays.asList(course));
Course[] course2 = {new Course("5", "高等数学"), new Course("6", "大学英语")};
coursesToSelect.addAll(2, Arrays.asList(course2));
}
public void testListContains() {
//取得备选课程序列的第0个元素
Course course = coursesToSelect.get(0);
//打印输出查看coursesToSelect是否包含course对象
System.out.println("取得课程:" + course.name);
System.out.println("备选课程中是否包含课程:" + course.name + "," + coursesToSelect.contains(course));
//提示输入新的课程名称
System.out.println("请输入课程名称:");
String name = console.next();
//创建一个新的课程对象,ID和名称,与course对象完全一样
Course course2 = new Course();
course2.name = name;
System.out.println("新创建课程:" + course2.name);
System.out.println("备选课程中是否包含课程:" + course2.name + "," + coursesToSelect.contains(course2));
}
public static void main(String[] args) {
SetTest2 st = new SetTest2();
st.testAdd();
st.testListContains();
}
}
运行结果:
containsAll方法:具体用法和前面详细介绍的removeAll等方法非常类似,具体不再赘述。
2.学生选课-判断Set中课程是否存在
写一个SetTest3类,也是在SetTest中的方法基础上进行改动的:
package com.imooc.collection;
import java.util.*;
public class SetTest3 {
public List<Course> coursesToSelect; //带有泛型Course的List类型属性
public Student student;
private Scanner console = new Scanner(System.in);
public SetTest3() {
this.coursesToSelect = new ArrayList<Course>();
}
public void testAdd() { //用于往coursesToSelect中添加备选课程
//创建一个课程对象,并通过调用add方法,添加到备选课程List中
Course cr1 = new Course("1", "数据结构");
coursesToSelect.add(cr1);
Course cr2 = new Course("2", "C语言");
coursesToSelect.add(0, cr2);
Course[] course = {new Course("3", "离散数学"), new Course("4", "汇编语言")};
//add方法是用来添加单个的Course对象的,而addAll方法是将一个集合List里的所有元素都添加到courseToSelect集合里去的。
//Arrays.asList方法不是用来添加对象的,而是用来将Course数组转化为集合的。
coursesToSelect.addAll(Arrays.asList(course));
Course[] course2 = {new Course("5", "高等数学"), new Course("6", "大学英语")};
coursesToSelect.addAll(2, Arrays.asList(course2));
}
//创建学生对象并选课
public void createStudentAndSelectCourses() {
//创建一个学生对象
student = new Student("1", "小明");
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: coursesToSelect) {
if(cr.id.equals(courseID)) {
student.courses.add(cr);
student.courses.add(cr); //验证Set中元素是不可重复的
}
}
}
}
//测试Set的contains方法
public void testSetContains() {
//提示输入课程名称
System.out.println("请输入学生已选的课程名称:");
String name = console.next();
//创建一个新的课程对象,ID和名称,与course对象完全一样
Course course2 = new Course();
course2.name = name;
System.out.println("新创建课程:" + course2.name);
System.out.println("备选课程中是否包含课程:" + course2.name + "," + student.courses.contains(course2));
}
public void testForEach() {
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) {
SetTest3 st = new SetTest3();
st.testAdd();
st.testForEach();
st.createStudentAndSelectCourses();
st.testSetContains();
}
}
运行结果:
一个奇怪的问题出现了,为什么这里显示的是false呢?
这是因为courses集合我们是用HashSet实现的,而在调用HashSet的contains方法的时候,其实是先调用了hashCode方法来返回哈希码,在哈希码的值相等的情况下才调用equals方法去判断是否相等,只有都相等的情况下才能认定这个HashSet包含某个元素:
所以我们要重写hashCode方法:
在Course类中右键点击空白处,选择generate,选择生成hashCode和equals,选择name属性(因为我们只需要判断name),然后系统就会自动为我们生成这两个方法,可以看到,equals方法和我们之前重写的并无两样。之后再去执行SetTest3中的主函数,就会返回true了。
@Override
public int hashCode() {
return Objects.hash(name);
}
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;
}
}
3.学生选课-获取List中课程的位置
写一个类SetTest4,也是对之前的代码做些改动:
package com.imooc.collection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class SetTest4 {
public List<Course> coursesToSelect; //带有泛型Course的List类型属性
private Scanner console;
public SetTest4() {
this.coursesToSelect = new ArrayList<Course>();
console = new Scanner(System.in);
}
public void testAdd() { //用于往coursesToSelect中添加备选课程
//创建一个课程对象,并通过调用add方法,添加到备选课程List中
Course cr1 = new Course("1", "数据结构");
coursesToSelect.add(cr1);
Course cr2 = new Course("2", "C语言");
coursesToSelect.add(0, cr2);
Course[] course = {new Course("3", "离散数学"), new Course("4", "汇编语言")};
//add方法是用来添加单个的Course对象的,而addAll方法是将一个集合List里的所有元素都添加到courseToSelect集合里去的。
//Arrays.asList方法不是用来添加对象的,而是用来将Course数组转化为集合的。
coursesToSelect.addAll(Arrays.asList(course));
Course[] course2 = {new Course("5", "高等数学"), new Course("6", "大学英语")};
coursesToSelect.addAll(2, Arrays.asList(course2));
}
public void testListContains() {
//取得备选课程序列的第0个元素
Course course = coursesToSelect.get(0);
//打印输出查看coursesToSelect是否包含course对象
System.out.println("取得课程:" + course.name);
System.out.println("备选课程中是否包含课程:" + course.name + "," + coursesToSelect.contains(course));
//提示输入新的课程名称
System.out.println("请输入课程名称:");
String name = console.next();
//创建一个新的课程对象,ID和名称,与course对象完全一样
Course course2 = new Course();
course2.name = name;
System.out.println("新创建课程:" + course2.name);
System.out.println("备选课程中是否包含课程:" + course2.name + "," + coursesToSelect.contains(course2));
//通过indexOf方法来取得某元素的索引位置
if(coursesToSelect.contains(course2))
System.out.println("课程:" + course2.name + "的索引位置为" + coursesToSelect.indexOf(course2));
}
public void testForEach() {
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) {
SetTest4 st = new SetTest4();
st.testAdd();
st.testListContains();
st.testForEach();
}
}
运行结果:
indexOf()方法与lastIndexOf()方法实现原理:
a.遍历调用每个元素的equals()方法,如果返回true则将次元素的索引返回
b.如果有多个相同元素,则只返回第一个元素的索引
c.lastIndexOf()方法则从最后一个元素开始遍历
d.indesOf 和lastIndexOf 方法如果未找到相关元素的话,返回值为-1
转载:https://blog.csdn.net/weixin_43684054/article/details/104655489