• 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

    乘风而归——只要抱着良好的愿望演奏,演员的演技可以不予苛求。
  • 相关阅读:
    Docker之路-docker架构
    Docker之路-认识docker
    Docker之路-版本选择及安装
    Golang理解-集合
    大话算法-动态规划算法
    运维职责
    Golang理解-匿名结构体
    DotNetty项目基本了解和介绍
    变量声明在循环体内还是循环体外的争论
    SqlServer与MySql语法比较
  • 原文地址:https://www.cnblogs.com/xuejiangbo/p/6687268.html
Copyright © 2020-2023  润新知