java-Collections工具类,Set Map接口,斗地主排序升级版

java-Collections工具类,Set Map接口,斗地主排序升级版

补充:泛型接口

子类实现泛型接口的时候,有三种方式

1.实现类丢弃泛型

class Zi implements A{

​ public void show(Object o){

​ }

}

2.实现类在实现接口时候指定具体反省类型

class Zi implements A {

​ public void show(String s){}

}

3.实现类延续接口泛型

class Ziimplements A{

​ public void show(T t){}

}

泛型通配符:

匹配任何累类型:<?>

匹配规定类型的本身以及其子类<? extends A>

匹配规定类型的本身以及其父类<? super A>

Collection 工具类

1.java.util.Collection类:是一个对Collection集合(List、Set)操作的工具类,里面提供了大量的静态方法,可以对集合进行打印,查找和排序。

1.1常用方法

1.public static void shuffle(List<?> list):打乱集合顺序。

2.public static<T extends Comparable<? super T>>:对集合元素按照自然排序规则进行排序。

3.public staticvoid sort(Listlist,Comparator<? super >c>):对集合按照比较器规则进行排序。

1.2 sort方法自排序

1.自排序:

public static <T extends Comparable<? super T>>void sort(Listlist):对集合元素按照自然排序规则进行排序,要求集合元素必须实现Comparable 接口冰重写comparaTo方法。

2.ComparaTo()方法

comparaTo返回的是一个int,三种情况:

正数:当前对象大于参数对象

负数:当前对象小于参数对象

0: 当前对象等于参数对象

3.String类以及自定义类对象集合排序:

package com.day06.Collections_sort方法自排序;

import java.util.Objects;

public class Student implements Comparable<Student> {
    private int age;

    public Student() {
    }

    public Student(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age;
    }

    @Override
    public int hashCode() {
        return Objects.hash(age);
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                '}';
    }

    @Override
    public int compareTo(Student o) {
        return this.getAge() - o.getAge();//升序
        //return o.getAge() - this.getAge();降序
    }
}
*********************************************
package com.day06.Collections_sort方法自排序;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Test {
    public static void main(String[] args) {
        //String 类型的排序
        ArrayList<String> strList = new ArrayList<>();
        String a = "n";
        String b = "a";

        strList.add(a);
        strList.add(b);
       Collections.sort(strList);
        System.out.println(strList);
        

        //自定义类
        //1.自定义类必须实现Comparable类,并且改写comparaTO方法
         ArrayList<Student> stuList = new ArrayList<>();
         stuList.add(new Student(25));
         stuList.add(new Student(28));
         stuList.add(new Student(21));

         Collections.sort(stuList);
        System.out.println(stuList);


    }
}


1.3 sort方法比较器排序(应用更方便)

public static void sort(List list ,Comparator<? super T>c):对集合按照比较器排序规则进行排序。

比较器排序的优先级要高于自排序
package com.day06.Collections_sort方法比较器排序;

import com.day06.Collections_sort方法自排序.Student;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Test {
    public static void main(String[] args) {
        //String 的
        ArrayList<String> strList = new ArrayList<>();
        String a = "n";
        String b = "a";

        strList.add(a);
        strList.add(b);

        Collections.sort(strList, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o2.compareTo(o1);
            }
        });
        System.out.println(strList);

        //基本类型封装类型,自排序对这些基本类型的只有升序,所以,需要降序或者其他排序方式,用这个方法。
        //并且,比较器排序的优先级要高于自排序
        ArrayList<Integer> intList = new ArrayList<>();
        intList.add(1);
        intList.add(12);
        intList.add(10);
        intList.add(19);

        Collections.sort(intList, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;//升序
                //return o2-o1;
            }
        });

        //自定义类型 自定义类不需要实现Comparable类。
        ArrayList<Student> stuList = new ArrayList<>();
        stuList.add(new Student(25));
        stuList.add(new Student(2589));
        stuList.add(new Student(252));
        Collections.sort(stuList, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getAge()- o2.getAge();
            }
        });
    }
}
练习:初始化学生对象存入集合中,对集合进行排序,先按照年龄进行排序,如果年龄相同,则按照分数排序
package com.day06.Collections_sort_练习;



import com.day06.Collections_sort方法自排序.Student;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Test {
    public static void main(String[] args) {
        //练习:初始化学生对象存入集合中,对集合进行排序,先按照年龄进行排序,如果年龄相同,则按照分数排序
        ArrayList<Student> stuList = new ArrayList<>();
        Student stu1 = new Student(25,15);
        Student stu2 = new Student(22,15);
        Student stu3 = new Student(25,18);
        Student stu4 = new Student(21,1);
        Student stu5 = new Student(28,10);

        stuList.add(stu1);
        stuList.add(stu2);
        stuList.add(stu3);
        stuList.add(stu4);
        stuList.add(stu5);

        Collections.sort(stuList, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                int a =o1.getAge()-o2.getAge();
                if(a==0){
                    int b = o1.getScore()-o2.getScore();
                }
                return a;
            }
        });
        System.out.println(stuList);
    }
}



可变参数

2.1可变参数的使用

确定类型,但是不确定数量的时候,可以使用

格式:数据类型 …数据名称 (意义等同于不确定长度的数组)

package com.day06.可变参数;

import com.day06.Collections_sort方法自排序.Student;

public class Test {
    public static void main(String[] args) {
        can(1,2,3);
        int[] arr={1,2,3};
        can(arr);
        can();
        //给拥有可变参数的方法定义实参时,可以使用规定类型的个体,也可以使用该类型数组.
        //如果方法中只有一个形参,并且可变参数,调用方法时候可以不传参
    }
    
    public static void can(int...arr){
        
    }
    public static void can(Student...Sarr){//相当于int[] arr
        
    }
    public static void can(int a ,String b ,int...arr){
        
    }
    public static  void  can (int...arr,int b ){}// 报错,可变参数只能放在形参的最末尾定义,所以,一个方法中,只能够拥有一个可变参
}

Set集合

3.1特点

1.无序

2.不可以存储重复元素

3.不可以通过索引访问元素

Set集合没有新增方法,都是集成Collection集合方法

Set集合是一个接口。

Set 集合有多个子类,这里我们介绍其中的 java.util.HashSet 、 java.util.LinkedHashSet 、 java.util.TreeSet 这两个集合。
tips:Set集合取出元素的方式可以采用:迭代器、增强for。

3.2 Set集合HashSet存储字符串

HashSet保证 元素唯一性的方式依赖于: hashCode 与 equals 方法。

package com.day06.Set集合使用;

import java.util.HashSet;
import java.util.Set;

public class Test {
    public static void main(String[] args) {
        Set<String> strList = new HashSet<>();
        strList.add("wo");
        strList.add("ai");
        strList.add("ni");
        strList.add("haha");
        strList.add("wo");

        System.out.println(strList);//[haha, wo, ai, ni] 无序存储,取出顺序不确定,不能存储重复元素
    }
}

3.3 Set集合HashSet存储自定义对象

存储自定义对象时,要求自定义对象必须重写hashCode和equals方法,会根据hashCode和equals方法判断元素是否重复。先调用对象的hashCode方法进行哈希值的判断,若哈希值相同,就会进行equals的判断。

package com.day06.Set集合使用.Set存储自定义参数;

import com.day06.Collections_sort方法自排序.Student;//该类重写了方法

import java.util.HashSet;
import java.util.Set;

public class Test {
    public static void main(String[] args) {
        Set<Student> studentSet = new HashSet<>();
        
        studentSet.add(new Student(25,26));
        studentSet.add(new Student(25,26));
        studentSet.add(new Student(25,26));

        System.out.println(studentSet);
    }
}

Set集合,哈希表结构:

public in hashCode();返回该对象的哈希码值,返回对象内存地址的十进制数。

哈希表存储方式是数组加链表。先判断元素的哈希值,按照数组方式存储。如果哈希值相同,则按照链表方式存储,当链表长度大于8时,会自动转化成为红黑树存储方式。

图示见文章末尾

Set集合_LInkedHashSet的特点以及使用

内部采用的是哈希表+链表存储元素,在哈希表基础上,多了一条链表,此链表记录的是元素的存储的顺序,所以,LInkedHashSet是有序的。

package com.day06.Set集合使用.LinkedHashSet使用;

import java.util.Iterator;
import java.util.LinkedHashSet;

public class Test {
    public static void main(String[] args) {
        //除了有序以外,其余的使用方法和HashSet没区别

        LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
        linkedHashSet.add("ni");
        linkedHashSet.add("hao");
        linkedHashSet.add("jaja");
        linkedHashSet.add("ni");
        linkedHashSet.add("ni");

        System.out.println(linkedHashSet);
        
        //迭代器遍历
        Iterator<String> iterator = linkedHashSet.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        
        //增强for遍历
        for (String s : linkedHashSet) {
            System.out.println(s);
        }
    }
}

Set集合,TreeSet的特点和使用

内部采用的是红黑树(平衡二叉树),要求元素有顺序,可以进行排序的。要求元素实现comparable接口并且重写comparaTo方法。

使用方面和HashSet一样,只不过是有顺序。

Map集合(双列集合)

数据结构都是作用在Key上的

**HashMap:**内部采用哈希表结构存储key,是通过hashcode和equals方法来判断key是否是重复的,要求key必须要重写hashcode和queals方法。

**LInkedHashMap:**内部采用的是哈希表加上链表存储结构存储key,在哈希表基础上多了一条链表,此链表记录的是key的存放顺序,所以LinkHashMap的key是有序的

**TreeMap:**内部采用红黑树(平衡二叉树)的结构存储key,要求key是可以进行排序的,所以key应该实现comparable接口,并且重写comparaTo方法。

Map集合基本操作:

package com.day06.Map使用;

import java.util.HashMap;
import java.util.Map;

public class Test {
    public static void main(String[] args) {
        Map<Integer,Integer> map = new HashMap<>();
        
        //增加和修改

        System.out.println(map.put(1,1));//NUll key=1的位置没有元素,所以返回null,相当于添加
        System.out.println(map.put(1,2));//null,key1的位置上有元素,返回被覆盖的元素,相当于修改
        
        //删除
        System.out.println(map.remove(1));//删除key = 1的value(元素)和key

        System.out.println(map.get(1));//查看key = 1位置上的元素
        System.out.println(map.containsKey(1));//查看集合之中是否有为1的Key 返回值为布尔值
        
    }
}

Map集合的两种遍历方式

1.键遍历

package com.day06.Map使用.键遍历;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Test {
    public static void main(String[] args) {
        Map<Integer,Integer> map = new HashMap<>();

        //增加和修改

        System.out.println(map.put(1,1));
        System.out.println(map.put(2,2));

        //键遍历
        Set<Integer> keys = map.keySet();//创建一个Set集合keys,存储map的key
        for (Integer key : keys) {
            System.out.println(map.get(key));//将keys中的集合利用get方法遍历
        }

    }
}

2.键值对遍历 比键遍历效率更高!

package com.day06.Map使用.键值对遍历;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Test {
    public static void main(String[] args) {
        Map<Integer,Integer> map = new HashMap<>();

        //增加和修改

        System.out.println(map.put(1,1));
        System.out.println(map.put(2,2));

        //键值遍历
        Set<Map.Entry<Integer, Integer>> entries = map.entrySet();
        for (Map.Entry<Integer, Integer> entry : entries) {
            System.out.println(entry.getKey());
            System.out.println(entry.getValue());
        }
    }
}

HashMap使用自定义对象做为键

内部采用的是哈希表数据结构存储key,要求自定义对象类必须重写equals()和hashCode()

LinkedHashMap

key有序,存取顺序一致。

TreeMap:

自定义对象作为key需要实现comparable接口并且重写comparaTo方法。因为有序

练习:计算每一个字符出现的次数

package com.day06.Map使用.计算每一个字符出现的顺序;


import java.util.HashMap;
import java.util.Map;

public class Test {

    public static void main(String[] args) {
        String str = "abcbch";
        Map<Character, Integer> map = new HashMap<>();
        //获取每一个字符
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);//获取每一个字符
            if (map.containsKey(c)) {//如果有此key
                int count = map.get(c);//取出对应value 出现的次数
                map.put(c, count + 1);
            } else {
                map.put(c, 1);
            }
        }
        System.out.println(map);
    }


}

斗地主排序版:

package com.day06.斗地主排序版;

import java.util.*;

public class Test {
    public static void main(String[] args) {
        //把每张牌,给予一个序号存入key,后续操作序号
        Map<Integer,String> pukerMap = new HashMap<>();
        int index = 0;

        String[] huaSe = {"♥","♦","♠","♣",};
        String[] paiMian = {"A","1","2","3","4","5","6","7","8","9","10","J","Q","K"};

        pukerMap.put(index++,"大王");
        pukerMap.put(index++,"小王");

        for (String h : huaSe) {
            for (String p : paiMian) {
                pukerMap.put(index++,h+p);
            }
        }

        ArrayList<Integer> pukerList = new ArrayList<>();
        //将key存入pukerList 进行排序,发牌操作
        Set<Integer> keys = pukerMap.keySet();
        for (Integer key : keys) {
            pukerList.add(key);
        }

        Collections.shuffle(pukerList);//洗牌

        //创建四个ArrayList集合
        ArrayList<Integer> player1 = new ArrayList<>();
        ArrayList<Integer> player2 = new ArrayList<>();
        ArrayList<Integer> player3 = new ArrayList<>();
        ArrayList<Integer> dipai = new ArrayList<>();
        for (int i = 0; i < pukerList.size(); i++) {
            if (i>=pukerList.size()-3){
                dipai.add(pukerList.get(i));
            }else if (i%3==0){
                player1.add(pukerList.get(i));
            }else if (i%3==1){
                player2.add(pukerList.get(i));
            }else if (i%3==2){
                player3.add(pukerList.get(i));
            }
        }

        //排序
        Collections.sort(dipai);
        Collections.sort(player3);
        Collections.sort(player2);
        Collections.sort(player1);
        
        //看牌
        kanPai(pukerMap,player1,"1");
        kanPai(pukerMap,player2,"2");
        kanPai(pukerMap,player3,"3");
        kanPai(pukerMap,dipai,"底牌");


    }
    //调取map里面的对应list里面的key的value
    public static  void kanPai(Map<Integer,String> map , ArrayList<Integer> list,String name){
        System.out.print(name+":");
        for (int i = 0; i < list.size(); i++) {
            System.out.print(map.get(list.get(i))+"  ");
        }
        System.out.println();


    }


}

哈希表
斗地主
遍历方式图解

猜你喜欢

转载自blog.csdn.net/qq_41371264/article/details/103684571