zoukankan      html  css  js  c++  java
  • 集合之 collection 迭代器 泛型 (任意类型)

    主要内容

    - Collection集合
    - 迭代器
    - 增强for
    - 泛型

    # 第一章 Collection集合

    1.1 集合概述

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

    集合和数组的区别

    * 数组的长度是固定的。集合的长度是可变的。
    * 数组中存储的是同一类型的元素,可以存储基本数据类型值。集合存储的都是对象。而且对象的类型可以不一致。在开发中一般当对象多的时候,使用集合进行存储。

    ## 1.2 集合框架

    集合按照其存储结构可以分为两大类,Collection`集合,Map集合。

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

    `List`的特点有序、可重复。`Set`的特点是无序,不可重复。

    `List`:ArrayLst 和 LinkList

     

    ## 1.3 Collection 常用功能

    Collection是所有单列集合的父接口,因此在Collection中定义了单列集合(List和Set)通用的一些方法,这些方法可用于操作所有的单列集合。方法如下:

    * `public boolean add(E e)`: 把给定的对象添加到当前集合中 。
    * `public void clear()` :清空集合中所有的元素。
    * `public boolean remove(E e)`: 把给定的对象在当前集合中删除。
    * `public boolean contains(E e)`: 判断当前集合中是否包含给定的对象。
    * `public boolean isEmpty()`: 判断当前集合是否为空。
    * `public int size()`: 返回集合中元素的个数。
    * `public Object[] toArray()`: 把集合中的元素,存储到数组中。

    方法演示:

    package com.itheima.demo01.Collection;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.HashSet;
    
    /*
        java.util.Collection接口
            所有单列集合的最顶层的接口,里边定义了所有单列集合共性的方法
            任意的单列集合都可以使用Collection接口中的方法
    
    
        共性的方法:
          public boolean add(E e):  把给定的对象添加到当前集合中 。
          public void clear() :清空集合中所有的元素。
          public boolean remove(E e): 把给定的对象在当前集合中删除。
          public boolean contains(E e): 判断当前集合中是否包含给定的对象。
          public boolean isEmpty(): 判断当前集合是否为空。
          public int size(): 返回集合中元素的个数。
          public Object[] toArray(): 把集合中的元素,存储到数组中。
     */
    public class Demo01Collection {
        public static void main(String[] args) {
            //创建集合对象,可以使用多态
            //Collection<String> coll = new ArrayList<>();
            Collection<String> coll = new HashSet<>();
            System.out.println(coll);//重写了toString方法  []
    
            /*
                public boolean add(E e):  把给定的对象添加到当前集合中 。
                返回值是一个boolean值,一般都返回true,所以可以不用接收
             */
            boolean b1 = coll.add("张三");
            System.out.println("b1:"+b1);//b1:true
            System.out.println(coll);//[张三]
            coll.add("李四");
            coll.add("李四");
            coll.add("赵六");
            coll.add("田七");
            System.out.println(coll);//[张三, 李四, 赵六, 田七]
    
            /*
                public boolean remove(E e): 把给定的对象在当前集合中删除。
                返回值是一个boolean值,集合中存在元素,删除元素,返回true
                                    集合中不存在元素,删除失败,返回false
             */
            boolean b2 = coll.remove("赵六");
            System.out.println("b2:"+b2);//b2:true
    
            boolean b3 = coll.remove("赵四");
            System.out.println("b3:"+b3);//b3:false
            System.out.println(coll);//[张三, 李四, 田七]
    
            /*
                public boolean contains(E e): 判断当前集合中是否包含给定的对象。
                包含返回true
                不包含返回false
             */
            boolean b4 = coll.contains("李四");
            System.out.println("b4:"+b4);//b4:true
    
            boolean b5 = coll.contains("赵四");
            System.out.println("b5:"+b5);//b5:false
    
            //public boolean isEmpty(): 判断当前集合是否为空。 集合为空返回true,集合不为空返回false
            boolean b6 = coll.isEmpty();
            System.out.println("b6:"+b6);//b6:false
    
            //public int size(): 返回集合中元素的个数。
            int size = coll.size();
            System.out.println("size:"+size);//size:3
    
            //public Object[] toArray(): 把集合中的元素,存储到数组中。
            Object[] arr = coll.toArray();
            for (int i = 0; i < arr.length; i++) {
                System.out.println(arr[i]);
            }
    
            //public void clear() :清空集合中所有的元素。但是不删除集合,集合还存在
            coll.clear();
            System.out.println(coll);//[]
            System.out.println(coll.isEmpty());//true
        }
    }

     

    ## 第二章 Iterator迭代器

    ## 2.1 Iterator接口

    `Iterator`与`Collection`、`Map`接口有所不同,`Collection`接口与`Map`接口主要用于存储元素,而`Iterator`主要用于迭代访问(即遍历)`Collection`中的元素,因此`Iterator`对象也被称为迭代器。

    想要遍历Collection集合,那么就要获取该集合迭代器完成迭代操作,下面介绍一下获取迭代器的方法:

    * `public Iterator iterator()`: 获取集合对应的迭代器,用来遍历集合中的元素的。

    Iterator接口的常用方法如下:

     E next()`:返回迭代的下一个元素。
     hasNext()`:如果仍有元素可以迭代,则返回 true。

        public static void main(String[] args) {
            //创建一个集合对象
            Collection<String> coll = new ArrayList<>();
            //往集合中添加元素
            coll.add("姚明");
            coll.add("科比");
            coll.add("麦迪");
            coll.add("詹姆斯");
            coll.add("艾弗森");
    
            /*
                1.使用集合中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接收(多态)
                注意:
                    Iterator<E>接口也是有泛型的,迭代器的泛型跟着集合走,集合是什么泛型,迭代器就是什么泛型
             */
            //多态  接口            实现类对象
            Iterator<String> it = coll.iterator();
    
            while(it.hasNext()){
                String e = it.next();
                System.out.println(e);
            }
            System.out.println("----------------------");
            for(Iterator<String> it2 = coll.iterator();it2.hasNext();){
                String e = it2.next();
                System.out.println(e);
            }

    ## 2.3 增强for

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

    public class Demo02Foreach {
        public static void main(String[] args) {
            demo02();
            demo01();
        }
    
        //使用增强for循环遍历集合
        private static void demo02() {
            ArrayList<String> list = new ArrayList<>();
            list.add("aaa");
            list.add("bbb");
            list.add("ccc");
            list.add("ddd");
            for(String s : list){
                System.out.println(s);
            }
        }
    
        //使用增强for循环遍历数组
        private static void demo01() {
            int[] arr = {1,2,3,4,5};
            for(int i:arr){
                System.out.println(i);
            }
        }
    }

     

    # 第三章 泛型

    ## 3.1 泛型概述

    在前面学习集合时,我们都知道集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们都会被提升成Object类型。当我们在取出每一个对象,并且进行相应的操作,这时必须采用类型转换。

    大家观察下面代码:

    package 泛型;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    
    public class Demo01Generic {
        public static void main(String[] args) {
            show02();show01();
        }
    
        /*
            创建集合对象,使用泛型
            好处:
                1.避免了类型转换的麻烦,存储的是什么类型,取出的就是什么类型
                2.把运行期异常(代码运行之后会抛出的异常),提升到了编译期(写代码的时候会报错)
             弊端:
                泛型是什么类型,只能存储什么类型的数据
         */
        private static void show02() {
            ArrayList<String> list = new ArrayList<>();
            list.add("abc");
            //list.add(1);//add(java.lang.String)in ArrayList cannot be applied to (int)
    
            //使用迭代器遍历list集合
            Iterator<String> it = list.iterator();
            while(it.hasNext()){
                String s = it.next();
                System.out.println(s+"->"+s.length());
            }
        }
    
        /*
            创建集合对象,不使用泛型
            好处:
                集合不使用泛型,默认的类型就是Object类型,可以存储任意类型的数据
            弊端:
                不安全,会引发异常
         */
        private static void show01() {
            ArrayList list = new ArrayList();
            list.add("abc");
            list.add(1);
    
            //使用迭代器遍历list集合
            //获取迭代器
            Iterator it = list.iterator();
            //使用迭代器中的方法hasNext和next遍历集合
            while(it.hasNext()){
                //取出元素也是Object类型
                Object obj = it.next();
                System.out.println(obj);
    
                //想要使用String类特有的方法,length获取字符串的长度;不能使用  多态 Object obj = "abc";
                //需要向下转型
                //会抛出ClassCastException类型转换异常,不能把Integer类型转换为String类型
                String s = (String)obj;
                System.out.println(s.length());
            }
        }
    }

     

    ## 3.2 使用泛型的好处

    上一节只是讲解了泛型的引入,那么泛型带来了哪些好处呢?

    * 将运行时期的ClassCastException,转移到了编译时期变成了编译失败。
    * 避免了类型强转的麻烦。

    通过我们如下代码体验一下:

    public class Demo02GenericClass {
        public static void main(String[] args) {
            //不写泛型默认为Object类型
            GenericClass gc = new GenericClass();
            gc.setName("只能是字符串");
            Object obj = gc.getName();
    
            //创建GenericClass对象,泛型使用Integer类型
            GenericClass<Integer> gc2 = new GenericClass<>();
            gc2.setName(1);
    
            Integer name = gc2.getName();
            System.out.println(name);
    
            //创建GenericClass对象,泛型使用String类型
            GenericClass<String> gc3 = new GenericClass<>();
            gc3.setName("小明");
            String name1 = gc3.getName();
            System.out.println(name1);
        }
    }
    package 泛型;
    /*
        测试含有泛型的方法
     */
    public class Demo03GenericMethod {
        public static void main(String[] args) {
            //创建GenericMethod对象
            GenericMethod gm = new GenericMethod();
    
            /*
                调用含有泛型的方法method01
                传递什么类型,泛型就是什么类型
             */
            gm.method01(10);
            gm.method01("abc");
            gm.method01(8.8);
            gm.method01(true);
    
            gm.method02("静态方法,不建议创建对象使用");
    
            //静态方法,通过类名.方法名(参数)可以直接使用
            GenericMethod.method02("静态方法");
            GenericMethod.method02(1);
        }
    }
    package 泛型;
    /*
        测试含有泛型的接口
     */
    public class Demo04GenericInterface {
        public static void main(String[] args) {
            //创建GenericInterfaceImpl1对象
            GenericInterfaceImpl1 gi1 = new GenericInterfaceImpl1();
            gi1.method("字符串");
    
            //创建GenericInterfaceImpl2对象
            GenericInterfaceImpl2<Integer> gi2 = new GenericInterfaceImpl2<>();
            gi2.method(10);
    
            GenericInterfaceImpl2<Double> gi3 = new GenericInterfaceImpl2<>();
            gi3.method(8.8);
           
        }
    }

    ?表示类型

    package 泛型;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    
    /*
        泛型的通配符:
            ?:代表任意的数据类型
        使用方式:
            不能创建对象使用
            只能作为方法的参数使用
     */
    public class Demo05Generic {
        public static void main(String[] args) {
            ArrayList<Integer> list01 = new ArrayList<>();
            list01.add(1);
            list01.add(2);
    
            ArrayList<String> list02 = new ArrayList<>();
            list02.add("a");
            list02.add("b");
    
            printArray(list01);
            printArray(list02);
    
            //ArrayList<?> list03 = new ArrayList<?>();
        }
    
        /*
            定义一个方法,能遍历所有类型的ArrayList集合
            这时候我们不知道ArrayList集合使用什么数据类型,可以泛型的通配符?来接收数据类型
            注意:
                泛型没有继承概念的
         */
        public static void printArray(ArrayList<?> list){
            //使用迭代器遍历集合
            Iterator<?> it = list.iterator();
            while(it.hasNext()){
                //it.next()方法,取出的元素是Object,可以接收任意的数据类型
                Object o = it.next();
                System.out.println(o);
            }
        }
    }

    ### 通配符高级使用----受限泛型

    之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置。但是在JAVA的泛型中可以指定一个泛型的**上限**和**下限**。

    **泛型的上限**:

    * **格式**: `类型名称 <? extends 类 > 对象名称`
    * **意义**: `只能接收该类型及其子类`

    **泛型的下限**:

    - **格式**: `类型名称 <? super 类 > 对象名称`
    - **意义**: `只能接收该类型及其父类型`

    比如:现已知Object类,String 类,Number类,Integer类,其中Number是Integer的父类

    package 泛型;
    
    import java.util.ArrayList;
    import java.util.Collection;
    
    /*
        泛型的上限限定: ? extends E  代表使用的泛型只能是E类型的子类/本身
        泛型的下限限定: ? super E    代表使用的泛型只能是E类型的父类/本身
     */
    public class Demo06Generic {
        public static void main(String[] args) {
            Collection<Integer> list1 = new ArrayList<Integer>();
            Collection<String> list2 = new ArrayList<String>();
            Collection<Number> list3 = new ArrayList<Number>();
            Collection<Object> list4 = new ArrayList<Object>();
    
            getElement1(list1);
            //getElement1(list2);//报错
            getElement1(list3);
            //getElement1(list4);//报错
    
            //getElement2(list1);//报错
            //getElement2(list2);//报错
            getElement2(list3);
            getElement2(list4);
    
            /*
                类与类之间的继承关系
                Integer extends Number extends Object
                String extends Object
             */
    
        }
        // 泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类
        public static void getElement1(Collection<? extends Number> coll){}
        // 泛型的下限:此时的泛型?,必须是Number类型或者Number类型的父类
        public static void getElement2(Collection<? super Number> coll){}
    }
    public class GenericClass<E> {
        private E name;
    
        public E getName() {
            return name;
        }
    
        public void setName(E name) {
            this.name = name;
        }
    }
    接口
    public interface GenericInterface<I> {
    public abstract void method(I i);
    }


    package 泛型; /* 含有泛型的接口第二种使用方式:接口使用什么泛型,实现类就使用什么泛型,类跟着接口走 就相当于定义了一个含有泛型的类,创建对象的时候确定泛型的类型 public interface List<E>{ boolean add(E e); E get(int index); } public class ArrayList<E> implements List<E>{ public boolean add(E e) {} public E get(int index) {} } */ public class GenericInterfaceImpl2<I> implements GenericInterface<I> { @Override public void method(I i) { System.out.println(i); } } 方法 package 泛型; /* 定义含有泛型的方法:泛型定义在方法的修饰符和返回值类型之间 格式: 修饰符 <泛型> 返回值类型 方法名(参数列表(使用泛型)){ 方法体; } 含有泛型的方法,在调用方法的时候确定泛型的数据类型 传递什么类型的参数,泛型就是什么类型 */ public class GenericMethod { //定义一个含有泛型的方法 public <M> void method01(M m){ System.out.println(m); } //定义一个含有泛型的静态方法 public static <S> void method02(S s){ System.out.println(s); } }

    # 第四章 集合综合案例

    ## 4.1 案例介绍

    按照斗地主的规则,完成洗牌发牌的动作。
    具体规则:

    使用54张牌打乱顺序,三个玩家参与游戏,三人交替摸牌,每人17张牌,最后三张留作底牌。

    ## 4.2 案例分析

    * 准备牌:

    牌可以设计为一个ArrayList<String>,每个字符串为一张牌。
    每张牌由花色数字两部分组成,我们可以使用花色集合与数字集合嵌套迭代完成每张牌的组装。
    牌由Collections类的shuffle方法进行随机排序。

    * 发牌

    将每个人以及底牌设计为ArrayList<String>,将最后3张牌直接存放于底牌,剩余牌通过对3取模依次发牌。


    * 看牌

    直接打印每个集合。

    ## 4.3 代码实现

    ~~~java
    import java.util.ArrayList;
    import java.util.Collections;

    public class Poker {
    public static void main(String[] args) {
    /*
    * 1: 准备牌操作
    */
    //1.1 创建牌盒 将来存储牌面的
    ArrayList<String> pokerBox = new ArrayList<String>();
    //1.2 创建花色集合
    ArrayList<String> colors = new ArrayList<String>();

    //1.3 创建数字集合
    ArrayList<String> numbers = new ArrayList<String>();

    //1.4 分别给花色 以及 数字集合添加元素
    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");
    //1.5 创造牌 拼接牌操作
    // 拿出每一个花色 然后跟每一个数字 进行结合 存储到牌盒中
    for (String color : colors) {
    //color每一个花色
    //遍历数字集合
    for(String number : numbers){
    //结合
    String card = color+number;
    //存储到牌盒中
    pokerBox.add(card);
    }
    }
    //1.6大王小王
    pokerBox.add("小☺");
    pokerBox.add("大☠");
    // System.out.println(pokerBox);
    //洗牌 是不是就是将 牌盒中 牌的索引打乱
    // Collections类 工具类 都是 静态方法
    // shuffer方法
    /*
    * static void shuffle(List<?> list)
    * 使用默认随机源对指定列表进行置换。
    */
    //2:洗牌
    Collections.shuffle(pokerBox);
    //3 发牌
    //3.1 创建 三个 玩家集合 创建一个底牌集合
    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<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);
    }else if(i%3==1){//玩家2
    player2.add(card);
    }else{//玩家3
    player3.add(card);
    }
    }
    }
    //看看
    System.out.println("令狐冲:"+player1);
    System.out.println("田伯光:"+player2);
    System.out.println("绿竹翁:"+player3);
    System.out.println("底牌:"+dipai);
    }
    }
    ~~~

     

  • 相关阅读:
    Android实现自适应正方形GridView
    关于ViewPager被嵌套在ScrollView中不显示的问题
    能够兼容ViewPager的ScrollView
    二二叉搜索树学习
    linux添加静态路由表,重新启动继续有效
    基于Cocos2dx + box2d 愤怒的小鸟的实现Demo
    2014牡丹江区域赛H(特里)ZOJ3826
    AIX加入能telnet远程连接方法的帐户
    函数返回值1的数量
    JQuery日记6.5 Javascript异步模式(一)
  • 原文地址:https://www.cnblogs.com/qj696/p/14305246.html
Copyright © 2011-2022 走看看