第一节 判断List中课程是否存在
思考:
1.在课程序列中如何判断会否包含某门或者某几门课程?
2.如果课程序列中包含某门课程,如何判断该课程的索引位置?
3.在创建Map时,我们用到的学生映射表中,如何判断是否包含某个学生ID?
4.又该如何判断是否包含某个对象呢
5.如果想把课程或者学生对象,按照课程名称或者学生姓名排序,又该怎么办,按照ID来排序呢?
1.如何判断集合中是否包含某个元素?无论是List还是Set判断的方法都是一样的,都是从Collection接口那继承的contains方法,contains,如果此列表中包含指定的元素,则返回ture。集合.contains(元素对象);这里需要注意的是,如果新建了一个对象,即使和之前的属性值一模一样,由于指向了不同的地址,返回的结果还会是false,不是包含在序列中的那个对象,即不包含。
测试List中的contais方法
public void containsTest(){
courseToSelect.get(0);
System.out.println("是否包含课程:"+courseToSelect.get(0).getName()+
":"+courseToSelect.contains(courseToSelect.get(0)));
Course cr=new Course("2","C语言");
System.out.println("是否包含课程:"+courseToSelect.contains(cr));
}
很多情况下我们只知道课程的名称,如何去判断某个序列下是否有这个元素呢?咱们可以通过for循环来遍历姓名,然后通过比较来得出结果,但往往这么做会比较麻烦。此时呢还可以使用contains方法。由此我们首先要分析一下contains方法的实现原理:
JAVA中所有类都继承与 Object类 equals(Object obj),contains(obj) 就是用集合中的元素去和obj比较,equals(obj),当咱们调用contains方法时其实就是遍历了List中的每一个元素,然后调用每个元素的equals方法去和咱们的contains方法中的参数相比较,如果有一个元素equals方法返回一个ture值,则contains方法也发返回一个true值,否则当所有结果都不返回true值时,contains方法就返回一个false值。
知道原理后其实我们只需要重写equals方法,去比较它们的name后,得出的结果就可以轻松实现判断是否包含名称为某个值的课程元素。
equals重写有快捷方式
public boolean equals(Object o) {
//boolean 需要输出一个布尔型的值 equals后面要有参数
if (this == o) return true;
//如果当前对象能够和object的参数,能用==号判断相等,那么肯定相等,返回ture
if (!(o instanceof Course)) return false;
//比较的是类型是否相同
Course course = (Course) o;
return getName().equals(course.getName());
}
重写之后再去比较返回的值就都是true了,因为比较的是课程名是否相等。containsAll 需要传进去的是一个collection类型的参数,如果列表包含指定Collection的所有元素,则返回ture
Course[] course1={new Course("100","C语言"),
new Course("101","汇编语言")};
System.out.println(courseToSelect.containsAll
(Arrays.asList(course1)));
第二节 判断Set中课程是否存在
新建一个学生对象并且存取课程后,用一个新的课程来读取输入的课程名字,比较课程Set中是否包含。结果为false因为需要重写哈希方法啊
public void setContains() {
Student st1 = new Student("1", "宫园薰");
System.out.println("欢迎" + st1.getName() + "同学选课!每位同学可以选取三门课程哦");
Scanner sc = new Scanner(System.in);
//for循环循环三次,通过对比ID来存入对应的课程信息
for (int i = 0; i < 3; i++) {
System.out.println("请输入您选择的课程ID:");
String courseId = sc.next();
for (Course cr : courseToSelect) {
if (courseId.equals(cr.getId())) {
st1.courses.add(cr);
break;
}
}
}
System.out.println("请输入您要查询的课程名字:");
Scanner sc2=new Scanner(System.in);
String name=sc2.next();
Course course=new Course(name);
System.out.println("宫园薰同学选择的课程中是否含有当前课程"+st1.courses.contains(course));
}
public int hashCode() {
return getName().hashCode();
}
equals和Hash方法都重写后比较结果正确。因为在咱们使用的HashSet实现的Set接口,,这需要从HashSet的 contains方法实现机制去解释。
Object equals方法 Hashcode()方法,HashCode方法返回的是对象哈希码的值,当咱们在调用HashSet的contains方法时,其实是先调用每一个元素,它的HashCode来返回它的哈希码,如果哈希码的值相等的情况下,再调用equals方法去判断是否相等。重写相当于是属性名字的哈希码。
第三节 学生选课--获取List中课程的位置
利用 集合.indexOf(课程)
indexOf(java)
equals (java) 大学英语 0
equals(java)高等数学 1
equals(java)java 2
equals(java)汇编语言 3
......
equals(java) java n
indexOf()实现机制:它跟contains方法类似,也是从序列的第0个位置的元素开始的,依次循环,并且调用每个元素的equals方法,和参数对象进行比较,如果某个元素的equals方法返回值为true,那么它就把当前索引位置作为结果返回,假如序列中有多个重复的元素,那么只返回第一次出现的索引位置的值。
还定义了LastIndexOf(java) 方法,返回某个元素最后一次出现的位置。无论是indexOf还是LastIndexOf()方法,如果它们的参数都没有在序列出现的话,结果会返回-1。
第四节 学生选课--判断Map中是否包含指定的key和value
Map中用containsKey来判断是否包含某个key值,用containsValue()方法来判断是否包含value值,Map中的containsValue方法也要调用equals方法,有需要的时候要重写后使用。
第五节 应用Collections.sort()方法实现List排序
Collections.sort(集合)排序,在第一季是使用过Arrays.sort()对数组进行升序排列。Collectioon工具类java.util.Collections;是JAVA集合框架中,用来操作集合对象的工具类,用来操作Collection对象的,这个Collectionos工具类本身也是JAVA集合框架的成员,跟Map Collection都是并列的,属于java集合框架。java在Collections中定义了一个sort排序方法,这也是咱们使用最多的一个方法。sort(); sort(List<7> list),按升序进行排序。下面的代码:
我们利用Random()创建一个新的随机数生成器,JAVA标准类库中有一个Random类,一个Random对象就可以生成很多随机数,包括随机的整数。
public class Test1 {
//通过collection.sort排序一个Integer泛型的List
public List<Integer> intsort;
public static void main(String[] args) {
Test1 ts=new Test1();
ts.intsort=new ArrayList<Integer>();
//添加100以内的随机整数
Random random=new Random();
Integer k=0;
for(int i=0;i<10;i++){
do{
//限制100以内随机数
k=random.nextInt(100);
}while(ts.intsort.contains(k));
ts.intsort.add(k);
}
for(Integer i:ts.intsort){
System.out.print(i);
System.out.print(" ");
}
System.out.println();
System.out.println("___________________");
Collections.sort(ts.intsort);
for(Integer i:ts.intsort){
System.out.print(i);
System.out.print(" ");
}
}
}
String泛型的类型排序,排列顺序 abcd,若首字母相同 则排第二个字母。
排序规则如下:
{
数字0-9
大写字母A-Z
小写字母a-z
}
第六节 尝试对学生序列排序
对于List < Integer > < 包装类 > < String >,collections.sort都是好用的,对于其他类型的List 如List < Student > 泛型,用collections.sort比较的列表中所有元素都必须实现comparable接口。Student类型不是comparable的实现类,所以直接比较时排序方法会报错。
comparable接口:java obj1 obj2 两者必须是可比较的,用comparable这个接口去表示某个对象是可以比较的,相当于是给对象定义了一个默认的排序规则,另一个接口comparator定义一个临时的比较规则的接口。
comparable 默认比较规则:
当一个类实现了comparable接口,它是可比较的。表示这个类的实例可以比较大小,可以进行自然排序。自然排序可以理解为定义了默认的比较规则。如果一个类实现了comparable接口,其实现类需实现compareTo()方法,当两个实现了comparable接口的类的实例进行比较的时候,就会调用这个compareTo()方法。如果A对象compareTo B对象,它的方法返回值是正数,则表示大,负数表示小,0表示相等。
comparator接口—比较工具接口
它的实现类,用于定义临时比较规则,而不是默认比较规则,如果某各类实现了comparator接口,需要实现compare()方法,comparator和comparable都是集合框架的成员,
JAVA集合框架 Collection接口 Map接口 Collections工具类,comparable接口 comparator接口。
第七节 实现学生序列排序
因为Student不能比较,改造Student类,implements Comparable<泛型>,实现这个接口,必须实现里面的compareTo方法,更改一下方法体用ID去比较,改造之后再去比较结果就可以了。
public class Student implements Comparable<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>();
}
public Student(){
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Student)) return false;
Student student = (Student) o;
return name.equals(student.name);
}
@Override
public int compareTo(Student o) {
return this.id.compareTo(o.id);
//o参数,当这个o对象和当前的student对象比较时,相等返回0,小的话正整数大的话负整数
}
}
关于Comparator方法,也是重写comepareTo方法
package imooccollection;
import java.util.Comparator;
/**
* Created by Administrator on 2017/3/21.
*/
public class StudentComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
//两个对象相等返回0. 1比2大,返回正整数,1比2小,返回负整数
return o1.name.compareTo(o2.name);
}
}
调用时用Collections.sort(students1,new StudentComparator());还是sort()方法,里面是集合还有一个新的comparator对象传递进去。
第八节 简易扑克牌游戏
综合练习——洗牌发牌Easy版
小结:遇到的问题
1.Scanner当输入错误的字符时无限循环,此时是由于Scanner在接收错误的字符后,重新循环还是那个错误的字符,需要做的是循环再次开始第一件事就是新建一个Scanner对象,这样就不会无限循环错误的结果了
2.comparable 在使用时实现了接口后需要实现compareTo方法,结果后面的o.调不出属性,原因是因为,在实现接口时没有指定泛型,这样就是Object类型,指定泛型后就可以使用相应的属性去比较了。
功能描述
一.创建一副扑克牌
包含四种花色:黑桃、红桃、梅花、方片
十三种点数:2-10,J,Q,K,A,不考虑大小王
二.创建两名玩家
玩家至少要有ID,姓名,手牌等属性,手牌为扑克牌的集合
三.洗牌
将之前创建的一副扑克牌顺序打乱
四.发牌
将洗牌之后的扑克牌集合,从第一张开始,发给两名玩家,按照一人一张的方法,每人发两张。
五.游戏
比较两名玩家手中的扑克牌,规则为:取两人各自手中点数最大的牌进行比较,点数大的赢。若两人各自的点数最大的牌相等,则再按照花色比较。黑红梅方,A>K
Card代码,里面是卡牌的属性,重写了equals方法,并且实现了Comparable接口。这里因为要求只是比较大小,所以我在属性里多添加了一条,用多加的这条属性来进行比较,由数字10,20,30,40,50,60,70,80,90,91,92,93,94还有颜色用A-D表示,组合而成的一个字符串,这样去排序看大小的话会非常方便。
因为一般的时候2是最大的牌。2用94,A93,K92,Q91,J90,10用80……3用10。后面跟着如果数字相同则比较花色,如黑红梅方,用DCBA来表示,比如说当都是2时,前两位都是94,方片2是94A,黑桃2就是94D。这样升序会排在对方后面。直接排序然后取最大的值就可以了。再用最大的值和当时的手牌去比较,相同的那位玩家获胜。
游戏运行的类
import java.util.ArrayList;
import java.util.Collections;
/**
* Created by Administrator on 2017/4/4.
*/
public class PokerGameTest {
public static void main(String[] args) {
System.out.println("--------欢迎来到扑克牌游戏--------");
System.out.println("------------创建扑克牌------------");
System.out.println("----------扑克牌创建成功----------");
System.out.print("扑克牌为:");
//创建卡牌集合类,实例化,调用方法创建52张的卡组
PokerCardsList pcl=new PokerCardsList();
pcl.pokerCardsListAdd();
System.out.println("------------开始洗牌-------------");
System.out.println("------------洗牌结束!------------");
System.out.println("------------创建玩家--------------");
PokerPlayerList pm=new PokerPlayerList();
//新建一个PokerPlayerList集合把这两个玩家存储进来
System.out.println("请输入第1位玩家的ID和姓名");
pm.playerIdNameAdd();
Player player1=pm.playerList.get(0);
System.out.println("请输入第2位玩家的ID和姓名");
pm.playerIdNameAdd();
Player player2=pm.playerList.get(1);
System.out.println("欢迎玩家:"+player1.playerName);
System.out.println("欢迎玩家:"+player2.playerName);
System.out.println("------------开始发牌-------------");
int[] k=pcl.randomTest();
Card player1Card1=new Card(pcl.pokerCardsList.get(k[0]).colorNum,
pcl.pokerCardsList.get(k[0]).colorSum);
Card player1Card2=new Card(pcl.pokerCardsList.get(k[1]).colorNum,
pcl.pokerCardsList.get(k[1]).colorSum);
Card player2Card1=new Card(pcl.pokerCardsList.get(k[2]).colorNum,
pcl.pokerCardsList.get(k[2]).colorSum);
Card player2Card2=new Card(pcl.pokerCardsList.get(k[3]).colorNum,
pcl.pokerCardsList.get(k[3]).colorSum);
//创建两个玩家的手牌List,实例化,否则会无法调用,空指针异常
player1.playerCardsList=new ArrayList<Card>();
player2.playerCardsList=new ArrayList<Card>();
player1.playerCardsList.add(player1Card1);
System.out.println("-----玩家:"+player1.playerName+"----拿牌");
player2.playerCardsList.add(player2Card1);
System.out.println("-----玩家:"+player2.playerName+"----拿牌");
player1.playerCardsList.add(player1Card2);
System.out.println("-----玩家:"+player1.playerName+"----拿牌");
player2.playerCardsList.add(player2Card2);
System.out.println("-----玩家:"+player2.playerName+"----拿牌");
System.out.println("------------发牌结束-------------");
System.out.println("------------开始游戏-------------");
Collections.sort(player1.playerCardsList);
System.out.println("玩家"+player1.playerName+"最大的手牌是:"+
player1.playerCardsList.get(1).colorNum);
Collections.sort(player2.playerCardsList);
System.out.println("玩家"+player2.playerName+"最大的手牌是:"+
player2.playerCardsList.get(1).colorNum);
Player nullPlayer=new Player();
nullPlayer.playerCardsList=new ArrayList<Card>();
nullPlayer.playerCardsList.add(player1.playerCardsList.get(1));
nullPlayer.playerCardsList.add(player2.playerCardsList.get(1));
Collections.sort(nullPlayer.playerCardsList);
if(nullPlayer.playerCardsList.get(1).equals(player1.playerCardsList.get(1))){
System.out.println("----------"+"玩家"+player1.playerName+"获胜"+"----------");
}else{
System.out.println("----------"+"玩家"+player2.playerName+"获胜"+"-----------");
}
System.out.println("玩家各自的手牌为:");
System.out.println("玩家"+player1.playerName+":"+player1.playerCardsList.get(0).colorNum+
" "+player1.playerCardsList.get(1).colorNum);
System.out.println("玩家"+player2.playerName+":"+player2.playerCardsList.get(0).colorNum+
" "+player2.playerCardsList.get(1).colorNum);
}
}
/**
* Created by Administrator on 2017/4/5.
* 定义一个卡牌类
*/
public class Card implements Comparable<Card>{
public String colorNum;
public String colorSum;
public Card(String colorNum,String colorSum) {
this.colorSum = colorSum;
this.colorNum=colorNum;
}
@Override
public int compareTo(Card o) {
return this.colorSum.compareTo(o.colorSum);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Card)) return false;
Card card = (Card) o;
return colorNum.equals(card.colorNum);
}
}
import java.util.*;
/**
* 游戏玩家类
* Created by Administrator on 2017/4/4.
*/
public class Player{
public Integer playerId;
public String playerName;
public List<Card> playerCardsList;
public Player(Integer playerId,String playerName){
this.playerId=playerId;
this.playerName=playerName;
List<Card> playerCardsList=new ArrayList<Card>();
}
public Player(){
}
}
import java.util.*;
/**
* Created by Administrator on 2017/4/5.
* 创建一整副卡牌的集合,由于要打乱卡牌的顺序
* 可以创建四个不重复的随机数,分别取牌发给玩家
*/
public class PokerCardsList {
public List<Card> pokerCardsList;
public PokerCardsList() {
this.pokerCardsList = new ArrayList<Card>();
}
/**
* 往pokerCardsList中添加卡牌的方法
*/
public void pokerCardsListAdd() {
final String[] Color = {"黑桃", "红桃", "梅花", "方片"};
final String[] Num = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
final String[] colorTwo={"D","C","A","B"};
final int[] sum={93,94,10,20,30,40,50,60,70,80,90,91,92};
for(int i = 0;i<4;i++){
for(int j=0;j<13;j++){
Card car=new Card(Color[i]+Num[j],sum[j]+colorTwo[i]);
pokerCardsList.add(car);
}
}
for(Card car:pokerCardsList){
System.out.print(car.colorNum+" ");
}
}
/**
* 抽牌的方法
* 输出四个随机数
*/
public int[] randomTest(){
Random num = new Random();
Set testSet=new HashSet();
for (int i=0,j=51;i<4&&j>47;j--){
testSet.add(num.nextInt(j));
if(testSet.size()>i){
i++;
}else{
continue;
}
}
//定义一个数组接收这四个数
int[] k=new int[4];
int i=0;
for(Object x:testSet) {
int y=(int)x;
k[i]=y;
i++;
}
return k;
}
}
import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.List;
import java.util.Scanner;
/**
* Created by Administrator on 2017/4/5.
*/
public class PokerPlayerList {
//创建一个List集合存放两名玩家的信息
public List<Player> playerList;
public PokerPlayerList(){
this.playerList=new ArrayList<Player>();
}
/**
* 存放玩家信息
*/
public void playerIdNameAdd() {
while(true) {
try {
Scanner sc=new Scanner(System.in);
System.out.println("输入ID:");
Integer playerid = sc.nextInt();
System.out.println("输入姓名:");
String playername = sc.next();
Player p = new Player(playerid, playername);
this.playerList.add(p);
break;
} catch (InputMismatchException e) {
System.out.println("您输入的ID非数字");
continue;
}
}
}
}
运行效果