JAVA集合基础04---泛型,Map集合,Collections与斗地主练习

JAVA集合基础04

泛型

泛型概述

  • jdk5引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型,它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数

  • 参数化类型顾名思义就是将原来的具体的类型参数化,然后在使用/调用时传入具体的类型,这种参数类型可以用在类,方法和接口中,分别被称为泛型类,泛型方法,泛型接口

  • 泛型定义格式

    • <类型>:指定一种类型的格式,这里的类型可以看成是形参
    • <类型1,类型2.....>:指定多种类型的格式,多种类型之间用逗号隔开,这里的类型可以看成是形参
    • 将来具体调用时给定的类型可以看成是实参,并且实参的类型只能是引用数据类型
  • 泛型的好处

    • 把运行时期的问题提前到了编译期间
    • 避免了强制类型转换

泛型类

泛型类的定义格式

  • 修饰符 class 类名<类型>{}
    public class Generic<T>{}//此处的T可以随便写为任意标识,常见的如T,E,K,V等形式的参数常用于表示泛型
    
  • 新建泛型类对象时可以将其设置为任意的形参类型

泛型方法

泛型方法的定义格式

  • 修饰符 <类型> 返回值类型 方法名(类型 变量名){}
    public <T> void show(T t){}//此处的T可以随便写为任意标识,常见的如T,E,K,V等形式的参数常用于表示泛型
    
  • 泛型方法不需要像泛型类一样在新建对象时要定义各种类型,只需要调用方法时传递任意类型参数即可

泛型接口

泛型接口的定义格式

  • 修饰符 interface 接口名<类型>{}
    public interface Generic<T>{}//此处的T可以随便写为任意标识,常见的如T,E,K,V等形式的参数常用于表示泛型
    

类型通配符

  • 为了表示各种泛型List的父类,可以使用类型通配符

  • 类型通配符:<?>

  • List<?>:表示元素类型未知的List,它的元素可以匹配任何的类型

  • 这种带通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中

  • 如果我们不希望List<?>是任何泛型List的父类,只希望它代表某一类泛型List的父类,可以只用类型通配符的上限

    • 类型通配符上限:<? extends 类型>
    • List<?extends Number>:它表示的类型是Number或者其子类
  • 也可以指定类型通配符的下限

    • 类型通配符下限:<? super 类型>
    • List<?super Number>:它表示的类型是Number或者其父类
  • 指定类型范围,避免开发不知道该数据只支持的范围,设置错误类型导致出现bug


可变参数

  • 可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变了

  • 格式:

    • 修饰符 返回值类型 方法名(数据类型...变量名){}
    • public static int sum(int...a){}
  • 注意事项

    • 这里的变量其实是一个数组
    • 如果包含多个参数,包含可变参数的情况下,要把可变参数放在最后
      • public static int sum(int b,int...a){}

可变参数的使用


Map集合

Map集合的概述和使用

Map集合概述

  • interface Map <K,V> K:键的类型;V:值的类型
  • 将键映射到值的对象,不能包含重复的键,每个键可以映射到最多一个值
  • 比如学生的学号和姓名: 001 林青霞

创建Map集合的对象

  • 多态的方式
  • 具体的实现类HashMap
public static void main(String[] args) {
    Map<String,String> m = new HashMap<String,String>();
    //添加元素
    m.put("id001","xuzhiyuan");
    m.put("id002","honghuihuang");
    m.put("id003","wuxiaofeng");

    //输出对象
    System.out.println(m);

}
  • 若是继续添加相同键的值,则会覆盖相同键的上一个值,Map集合的实现类对象HashMap的底层是哈希表,保证了键的唯一性

Map集合的基本功能

Map集合的获取功能

Map集合的遍历(方式1)

  • 获取所有键的集合,用keySet()集合方法实现
  • 遍历键的集合,获取到每一个键,用增强for实现
  • 根据键去找值,用get(Object key)方法实现
public static void main(String[] args) {
    Map<String, String> m = new HashMap<String, String>();
    //添加元素
    m.put("id001", "xuzhiyuan");
    m.put("id002", "honghuihuang");
    m.put("id003", "wuxiaofeng");

    //获取所有key的集合
    Set<String> ss = m.keySet();
    //遍历key集合后,利用get方法获取key的值
    for (String key : ss) {
        String value = m.get(key);
        System.out.println(key + "," + value);
    }
}

Map集合的遍历(方式2)

  • 获取所有键值对象的集合

    • Set<Map.Entry<K,V>>entrySet()//获取所有键值对对象的集合
      
  • 遍历键值对对象的集合,得到每一个键值对对象

    • 用增强for实现,得到每个Map.Entry
  • 根据键值对对象获取键和值

    • 用getKey()获取键
    • 用getValue()获取值
public static void main(String[] args) {
    Map<String, String> m = new HashMap<String, String>();
    //添加元素
    m.put("id001", "xuzhiyuan");
    m.put("id002", "honghuihuang");
    m.put("id003", "wuxiaofeng");

    Set<Map.Entry<String, String>> entrySet = m.entrySet();

    for (Map.Entry<String, String> me : entrySet) {
        String key = me.getKey();
        String value = me.getValue();
        System.out.println(key + "," + value);
    }
}

集合嵌套ArrayList嵌套HashMap

集合嵌套HashMap嵌套ArrayList

统计字符串中每个字符出现的次数

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入一个字符串:");
    String line = sc.nextLine();

    HashMap<Character, Integer> hm = new HashMap<Character, Integer>();

    for (int i = 0; i < line.length(); i++) {
        char key = line.charAt(i);
        Integer value = hm.get(key);

        if(value == null){
            hm.put(key,1);
        }else{
            value++;
            hm.put(key,value);
        }
    }
    StringBuilder sb = new StringBuilder();
    Set<Character> keyset = hm.keySet();
    for (Character c : keyset) {
        Integer value = hm.get(c);
        sb.append(c).append("(").append(value).append(")");
    }

    String s = sb.toString();
    System.out.println(s);
}

Collections概述和使用

  • Collection是一个单列集合的顶层,而Collections是一个具体的类,其中只有静态方法
  • 是针对集合操作的工具类

public static void main(String[] args) {
    List<Integer> list = new ArrayList<Integer>();

    list.add(50);
    list.add(30);
    list.add(10);
    list.add(40);
    list.add(20);

    //Collections.sort(list);
    //Collections.reverse(list);
    //Collections.shuffle(list);

    System.out.println(list);

}

模拟斗地主初版

public static void main(String[] args) {
    //创建一个牌盒,用ArrayList集合实现
    ArrayList<String> array = new ArrayList<String>();

    //往牌盒里装牌
    /*♦2,3.....A
      ♣2,3.....A
      ♥2,3.....A
      ♠2,3.....A
      大王,小王
     */
    //定义花色数组
    String[] colors = {"♦", "♣", "♥", "♠",};
    //定义一个点数数组
    String[] numbers = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"};
    for (String color : colors) {
        for (String number : numbers) {
            array.add(color + number);
        }
    }
    array.add("小王");
    array.add("大王");

    //洗牌
    Collections.shuffle(array);

    //发牌,遍历集合,给三个玩家发牌
    ArrayList<String> player1 = new ArrayList<String>();
    ArrayList<String> player2 = new ArrayList<String>();
    ArrayList<String> player3 = new ArrayList<String>();
    ArrayList<String> dipai = new ArrayList<String>();

    for (int i = 0; i < array.size(); i++) {
            String poker = array.get(i);
            int num = i % 3;
            if (i <= 2) {
                dipai.add(poker);
            } else if (num == 0) {
                player1.add(poker);
            } else if (num == 1) {
                player2.add(poker);
            } else if (num == 2) {
                player3.add(poker);
            }

        }
    //看牌
    lookPoker("xuzhiyuan",player1);
    lookPoker("chanchan",player2);
    lookPoker("lulu",player3);
    lookPoker("底牌",dipai);
}

//看牌的方法
public static void lookPoker(String name, ArrayList<String> array) {
    System.out.println(name + "的牌是:");
    for (String poker : array) {
        System.out.print(poker + " ");
    }
    System.out.println();
}

模拟斗地主升级版

public static void main(String[] args) {
    //创建HashMap集合,键是编号,值是牌
    HashMap<Integer, String> hm = new HashMap<Integer, String>();

    //创建ArrayList集合,存储编号
    ArrayList<Integer> array = new ArrayList<Integer>();

    //定义花色数组
    String[] colors = {"♦", "♣", "♥", "♠",};
    //定义一个点数数组
    String[] numbers = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};

    //从0开始往HashMap里存储键和值,同时也往ArrayList里存储键
    int index = 0;

    for (String number : numbers) {
        for (String color : colors) {
            hm.put(index, color + number);
            array.add(index);
            index++;
        }
    }

    hm.put(index, "小王");
    array.add(index);
    index++;

    hm.put(index, "大王");
    array.add(index);

    //洗牌,使用Collections的shuffle方法实现,洗的是编号
    Collections.shuffle(array);

    //发牌,发的是编号,为了保证编号是排序的,创建TreeSet集合来接受
    TreeSet<Integer> xzy = new TreeSet<Integer>();
    TreeSet<Integer> chan = new TreeSet<Integer>();
    TreeSet<Integer> lu = new TreeSet<Integer>();
    TreeSet<Integer> dipai = new TreeSet<Integer>();

    for (int i = 0; i < array.size(); i++) {
        int x = array.get(i);
        int num = i % 3;
        if (i <= 2) {
            dipai.add(x);
        } else if (num == 0) {
            xzy.add(x);
        } else if (num == 1) {
            chan.add(x);
        } else if (num == 2) {
            lu.add(x);
        }
    }
    lookPoker("xuzhiyuan", xzy, hm);
    lookPoker("chanchan", chan, hm);
    lookPoker("lulu", lu, hm);
    lookPoker("底牌", dipai, hm);

}

//定义方法看牌(遍历Treeset集合,获取编号,到HashMap集合中找到对应的牌
public static void lookPoker(String name, TreeSet<Integer> ts, HashMap<Integer, String> hm) {
    System.out.print(name + "的牌是: ");
    for (Integer key : ts) {
        String s = hm.get(key);
        System.out.print(s + " ");
    }
    System.out.println();
}
posted @ 2022-05-17 18:58  Joe_ximu  阅读(41)  评论(0)    收藏  举报