JAVA中的集合框架(下)

第一节 判断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;
            }
        }
    }
}

运行效果

Paste_Image.png

乘风而归——只要抱着良好的愿望演奏,演员的演技可以不予苛求。
原文地址:https://www.cnblogs.com/xuejiangbo/p/6687268.html