Tips:样式蚂蚁森林浇水get

java进阶——day02-1 Collection、泛型

Collection集合

集合概述

  集合是java中提供的一种容器,可以用来存储多个数据。

  集合和数组都是容器,他们之间的区别:

  1.数组的长度是固定的,集合的长度是可变的

  2.数组中存储的是同一类元素,数组存储基本数据类型值。而集合存储的是对象。而且对象的类型可以不一致。早开发中对象多的时候,使用集合进行存储。

集合框架  

  集合按照其存储结构可以分为两大类,分别是单列集合java.util.Collection 和 双列集合java.util.Map.

  Collection集合:单列集合类的根接口,用于存储一系列符合某种规则的元素,java.util.List 和 java.util.Set是它的两个重要子接口

  List接口:主要实现类有java.util.ArrayList 和 java.util.LinkedList

  set接口:注意实现类有java.util.HashSet 和java.util.TreeSet

 

  注意:集合本身是一个工具,放在java.util包中。在Collection接口定义着单列集合框架中具有共性的内容。且Collection不能直接创建对象

 

 Collection常用功能

  1.概述  

  Collection是所有单列集合的父接口,其中定义了单列集合(List和Set)通用的方法,这些方法用于操作所有的单列集合。

  2.方法

  

   3.方法使用

package day03;

import java.util.ArrayList;
import java.util.Collection;

public class day03_1 {
    //Collection操作单列集合的方法
    public static void main(String[] args) {
        //使用多态形式 创建集合对象
        Collection<String> collStr = new ArrayList<String>();
        //方法1---添加对象
        ((ArrayList<String>) collStr).add("马冬梅");
        ((ArrayList<String>) collStr).add("晓晓");
        ((ArrayList<String>) collStr).add("夏洛");
        System.out.println(collStr);//[马冬梅, 晓晓, 夏洛]

        //方法2---判断当前集合是否存在指定对象
        System.out.println("马冬梅 是否存在集合?:"+collStr.contains("马冬梅"));//true

        //方法3---删除在集合中的指定元素
        System.out.println("删除 晓晓:"+((ArrayList<String>) collStr).remove("晓晓"));//true
        System.out.println("晓晓 是否还存在于集合中?:"+collStr.contains("晓晓"));//false

        //方法4---查看集合有多少个元素
        System.out.println("集合中共存在:"+collStr.size()+" 个元素");

        //方法5---将集合 转换俄日Object数组
        Object[] objects = collStr.toArray();
        for (int i = 0; i < objects.length; i++) {
            System.out.println(objects[i]);
        }

        //方法6---清空集合
        collStr.clear();
        System.out.println(collStr);//[]

        //方法7---判断集合是否为空
        System.out.println(collStr.isEmpty());//true
    }
}
Collection方法

  注意:这些方法在单列集合是通用的

Iterator迭代器

Iterator接口

  1、作用:遍历Collection集合

    public Itterator iterator:获取集合对应的迭代器,用来遍历集合中的元素

  2、迭代:

  即Collection集合元素通用获取方式。在取元素之前要判断集合中有没有元素(isEmpty方法),如果有就把元素取出来,继续判断取出,直到取出集合中的所有元素。

  3、迭代器使用步骤:

  1.使用集合中的方法iterator(),获取迭代器的实现类对象,使用Iterator接口接收(多态)

  2.使用Iterator接口中的方法hasNext()判断还有没有下一个元素

  3.使用Iterator接口中的next()方法取出集合中的下一个元素

  4、使用

package day03;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class day03_2 {
    //迭代器的使用
    public static void main(String[] args) {
        //创建集合
        Collection<String> collStr = new ArrayList<>();
        //添加元素
        ((ArrayList<String>) collStr).add("张一山");
        ((ArrayList<String>) collStr).add("杨紫");
        ((ArrayList<String>) collStr).add("宋丹丹");

        //调用 集合中的iterator()方法 用Iterator对象接收
        Iterator<String> it = collStr.iterator();
        //遍历
        while (it.hasNext()){
            //取出元素
            String s = it.next();
            System.out.println(s);
        }
        /**
         * 张一山
         * 杨紫
         * 宋丹丹
         */
    }
}
Iterator

  5、注意

  在进行集合元素取出时,如果集合中没有元素了,还继续使用迭代器的next方法,将会 发生没有集合元素异常 错误

迭代器的原理

 

  在调用next方法之前,迭代器的索引位于第一个元素之前,不指向任何元素。

  当第一次调用迭代器的next方法后,迭代器的索引会向后移动一位,指向第一个元素并返回

  再次调用next方法时,迭代器索引会指向第二个元素并返回.......

  以此类推,直到hasNext方法返回false,表示到达集合的末尾,终止对集合的遍历

 

 增强for

  1、概述:  

增强for循环(for each),是JDK1.5后出的高级for循环,专门用来遍历数组和集合。它的内部原理其实是一个迭代器。所以在遍历过程中,不能对集合的元素进行增删操作

  2、格式:

   for(元素的数据类型 变量:Collection集合 或 数组){

    方法体}

  3、例如

package day03;

import java.util.ArrayList;
import java.util.Collection;

public class day03_3 {
    public static void main(String[] args) {
        Collection<String> collStr = new ArrayList<>();
        ((ArrayList<String>) collStr).add("何炅");
        ((ArrayList<String>) collStr).add("谢娜");
        ((ArrayList<String>) collStr).add("吴昕");
        //遍历集合
        for (String str: collStr
             ) {
            System.out.println(str);
        }
    }
}
for each--遍历集合
package day03;

public class day03_4 {
    public static void main(String[] args) {
        int[] arr = {1,3,5,7,9};
        //遍历数组
        for(int i : arr){
            System.out.println(i);
        }
    }
}
for each--遍历数组

  4、注意

  for each循环必须有被遍历的目标。目标只能是Collection集合数组

泛型

泛型概念

  Collection集合可以存储各种类型的对象,但实际上通常Collection集合只存储同一类型的对象,例如字符串对象(JDK5前存储其他类型会报错)。

  所以在JDK5以后,新增了泛型(Generic)语法,使在设计API时可以指定类或方法支持泛型

  泛型:是一种未知的数据类型,当我们不知道用什么类型的时候,就使用泛型。

  泛型可以看做一个变量 用来接收数据

泛型的定义和使用

1、对比

  1.不使用泛型

package day03;

import java.util.ArrayList;
import java.util.Iterator;

public class day03_5 {
    public static void main(String[] args) {
        //创建不使用泛型的集合
        ArrayList arr = new ArrayList();
        //添加数据 不使用泛型 集合默认类型为Object类型,可以存储任何数据类型
        //添加字符串类型数据
        arr.add("hello");
        //添加int类型
        arr.add(1);
        System.out.println(arr); //[hello, 1]
        //通过迭代器遍历
        Iterator it = arr.iterator();
        while (it.hasNext()){
            //取出元素 接收也是Object 并使用String的length属性 查看长度
            Object obj = it.next();
            System.out.print(obj+" ");//hello 1
            //将Object向下转型 转为String型
            String str = (String)obj;
            System.out.println(str.length());
            //输出会报出java.lang.ClassCastException异常 不能把Integer类型转为字符串
        }

    }
}
不使用泛型定义集合

  优点:

  集合不使用泛型,默认类型为object类型,可以存储任意类型数据

  缺点:

    不安全,会引发异常

  2.使用泛型

package day03;

import java.util.ArrayList;
import java.util.Iterator;

public class day03_6 {
    public static void main(String[] args) {
        ArrayList<String> arr = new ArrayList<>();
        //指定类型 String类
        arr.add("胡一菲");
        arr.add("曾小贤");
        arr.add("吕小布");
//        arr.add(1)  当添加不同类型时 会报错
        //使用迭代器遍历
        Iterator<String> iterator = arr.iterator();
        while (iterator.hasNext()){
            //创建String对象接收
            String str = iterator.next();
            System.out.print(str+" ");
            System.out.println(str.length());
        }
    }
}
使用泛型

  优点:

  1、避免了类型转换的麻烦,存储什么类型,取出的就是什么类型

  2、把运行期间的异常,提升到编译期(写代码时就会抛出错误)

  缺点:

  泛型是什么类型,就只能存什么类型

2、定义和使用含有泛型的类

  定义格式:

  修饰符 class 类名<代表泛型的变量>{}

  例如:

  ArrayList集合

package day03;

/**
 * 定义一个含有泛型的类 模拟ArrayList集合
 *
 */
public class GenericClass<E>{
    private E name;
    private E age;

    public E getName() {
        return name;
    }

    public E getAge() {
        return age;
    }

    public void setName(E name) {
        this.name = name;
    }

    public void setAge(E age) {
        this.age = age;
    }
}
泛型类的--定义
package day03;

public class GC_demo {
    public static void main(String[] args) {
        //变量E现在指定为 String类型
        GenericClass<String> gcC = new GenericClass<>();
        //只能传递String类型的数据
        gcC.setName("海鸥");
        gcC.setAge("18");
        System.out.println(gcC.getName()+"---"+gcC.getAge());//海鸥---18

        //变量E指定为 Integer类型
        GenericClass<Integer> gcC2 =new GenericClass<>();
        //只能传递Integer类型的数据
        gcC2.setName(23);
        gcC2.setAge(18);


    }
}
泛型类的--使用

  变量E在定义的时候是没有指定类型的,在这里代表未知的一种数据类型,未来传递什么类型就是什么类型

3、含有泛型的方法

  定义格式:

  修饰符 <代表泛型的变量> 返回值类型 方法名(参数){};

  例如:

package day03;
//此处的MVP 在这里代表未知的数据类型
public class MyGeneric<MVP> {
    private MVP mvp;

    public MVP getMvp() {
        return mvp;
    }

    public void setMvp(MVP mvp) {
        this.mvp = mvp;
    }
    //定义含有泛型的方法
    public <MVP> void show(MVP mvp){
        System.out.println(mvp.getClass());
    }

    public <MVP> MVP show2(MVP mvp){
        return mvp;
    }
}
含泛型的方法
package day03;

public class UseMyGc {
    public static void main(String[] args) {
        //创建泛型 指定String类型
        MyGeneric<String> mvp = new MyGeneric<>();
        mvp.setMvp("this is Generic Class!!!");
        System.out.println(mvp.getMvp());

        //调用含有泛型的方法
        mvp.show("abc");//class java.lang.String
    }
}
main

4、含泛型的接口

  定义格式:

  修饰符 interface 接口名<代表泛型的变量>{}

  例如:

package day03;
//定义泛型接口
public interface InterfaceGerneric<E> {
    //添加抽象方法
    public abstract void add(E a);
}
interface
package day03;
//定义泛型接口的 实现类
public class implements_IGC<E> implements InterfaceGerneric<E>{
    //重写抽象方法
    @Override
    public void add(E a) {
        System.out.println("您添加的内容为:"+a);
    }
}
implements
package day03;
//测试泛型接口
public class Inter_imp_Gc {
    public static void main(String[] args) {
        //指定为String类型
        implements_IGC<String> test = new implements_IGC<>();
        test.add("字符串测试");
        //指定为Integer类型
        implements_IGC<Integer> test2 =new implements_IGC<>();
        test2.add(1);
    }
}
main

  使用格式:

  1.定义类或者接口时 就确定泛型

  

 

  此时,泛型E的值为String类型

  2、定义时不确定泛型,直到创建对象时,确定泛型的类型

  

 

  确定泛型

 

 集合综合练习

练习说明:

  按照斗地主的规则,完成洗牌发牌的动作。 具体规则:
  使用54张牌打乱顺序,三个玩家参与游戏,三人交替摸牌,每人17张牌,最后三张留作底牌。

案例分析:

  准备牌:
  牌可以设计为一个ArrayList,每个字符串为一张牌。 每张牌由花色数字两部分组成,我们可以使用花色集合与数字集合嵌套迭代完成每张牌的组装。 牌由Collections类的shuffle方法进行随机排序。
  发牌
  将每个人以及底牌设计为ArrayList,将最后3张牌直接存放于底牌,剩余牌通过对3取模依次发牌。
  看牌
  直接打印每个集合。

实现:

package day03;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;

public class Poker {

    public static void main(String[] args) {
        //准备牌操作
        //创建牌盒 用来存储牌面
        ArrayList<String> pokerBox = new ArrayList<>();
        //创建存储花色集合
        ArrayList<String> colors = new ArrayList<>();
        //创建存储数字的集合 为什么用String型? 因为有JQKA
        ArrayList<String> numbers = new ArrayList<>();

        //添加花色
        colors.add("♥");
        colors.add("♦");
        colors.add("♠");
        colors.add("♣");
        //添加数字
        for (int i = 2; i <= 10; i++) {
            numbers.add(i+"");
        }
        numbers.add("J");numbers.add("Q");numbers.add("K");numbers.add("A");
        //创建牌 拼接牌
        //一个花色 然后跟每个数字 进行拼接
        for(String color:colors){
            //color每个花色
            //遍历numbers集合
            for(String number:numbers){
                //结合
                String card = color+number;
                pokerBox.add(card);
            }
        }
        //添加大小王
        pokerBox.add("小☺");
        pokerBox.add("大☠");

        //洗牌
        Collections.shuffle(pokerBox);
        //发牌
        //创建三个玩家 以及底牌集合
        ArrayList<String> player1 = new ArrayList<>();
        ArrayList<String> player2 = new ArrayList<>();
        ArrayList<String> player3 = new ArrayList<>();
        ArrayList<String> dipai = new ArrayList<>();

        //遍历牌盒
        for (int i = 0; i < pokerBox.size(); i++) {
            //获取每一张牌的牌面
            String card = pokerBox.get(i);
            //留取三张地主牌
            if(i>=51){
                dipai.add(card);
            }else {
                //玩家1 %3 ==0
                if(i%3 ==0){
                    player1.add(card);//玩家1
                }else if(i%3==1){
                    player2.add(card);//玩家2
                }else {
                    player3.add(card);
                }
            }
        }
        System.out.println("张三"+player1+" "+player1.size());
        System.out.println("李四"+player2+" "+player2.size());
        System.out.println("王五"+player3+" "+player3.size());
        System.out.println(dipai+" "+dipai.size());
    }
}
poker

 

posted @ 2021-03-16 20:24  心岛未晴  阅读(89)  评论(0)    收藏  举报