Java之集合Collection

集合

初次学习集合过程中的学习笔记,学习顶层,使用底层.包括常用的API

Collection接口

概述

  • 集合 : 集合是Java中提供的一种容器,可以用来存储多个数据.
与数组的区别:
  • 数组的长度是固定的,集合的长度是可变的.
  • 数组只能存储同一种数据类型,集合可以存储任意数据类型.
  • 数组可以存储基本数据类型和引用数据类型,集合只能存储引用数据类型.

集合的继承结构

集合的继承结构

List特点 : 存储有序(存取顺序一致),有索引,可以存储重复的元素
Set特点 : 存储无序(LinkedHashSet除外),没有索引,不可以存储重复的元素

共性方法

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

迭代器

迭代器用来遍历集合,使用下面的方法来创建迭代器:

  • Iterator iterator() 返回此集合中元素的迭代器。

迭代器中常用方法:

  • boolean hasNext() 如果迭代具有更多元素,则返回 true 。
  • E next() 返回迭代中的下一个元素。

如何遍历集合? 如下:

 // 创建集合
ArrayList<Student> stuList = new ArrayList<>();
// 创建学生对象
Student stu1 = new Student("赵丽颖",23);
stuList.add(stu1);
stuList.add(new Student("郑爽",22));
stuList.add(new Student("杨幂",34));
stuList.add(new Student("迪丽热巴",22));
// 使用迭代器进行遍历
Iterator<Student> iterator = stuList.iterator();
while(iterator.hasNext()){
    System.out.println(iterator.next());
}
System.out.println("=======================");
// 使用增强for循环的遍历
for (Student student : stuList) {
    System.out.println(student);
}
System.out.println("=======================");
// 使用数组进行遍历,注意的是只能用Object数组进行接收
Object[] objs = stuList.toArray();
for (int i = 0; i < objs.length; i++) {
    System.out.println(objs[i]);
}

增强for循环

增强for循环(也称for each循环)是JDK1.5以后出来的一个高级for循环,遍历集合内部原理其实是个Iterator迭代器,所以它只进行遍历元素,不要在遍历的过程中对集合元素进行增删操作。遍历数组内部原理其实是个普通for循环.
就是上面的第二种方式

新for循环必须有被遍历的目标。目标只能是Collection或者是数组。新式for仅仅作为遍历操作出现。

泛型

概念

广泛的数据类型,将数据类型的确认推迟到使用的时候.
泛型只能是引用数据类型.

泛型类的定义

在定义类的时候,在类名后加上,例如:

class A<E>{
}

泛型类在创建对象的时候确定类型.

定义含有泛型的方法

格式如下:
修饰符 <泛型> 返回值 方法名(泛型参数列表){}
例子:

public <E> void method1(E e){
    System.out.println(e);
}

使用的时候创建对象,调用方法,可以传入各种数据类型.

定义泛型的接口

格式如下:
interface 接口名{}

泛型接口的子实现类有两种方式:

  • 带泛型的 : class 类名 implements 接口名{}
  • 不带泛型的 : class 类名 implements 接口名{}

也就是说实现的子接口可以确定泛型的类型,也可以不确定,继续使用泛型,这就是两种方式.

泛型通配符

当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用.
不知道使用什么类型来接收的时候,此时可以使用?,?表示未知通配符。
例子:

public static void main(String[] args) {
    Collection<Intger> list1 = new ArrayList<Integer>();
    getElement(list1);
    Collection<String> list2 = new ArrayList<String>();
    getElement(list2);
}
public static void getElement(Collection<?> coll){}
//?代表可以接收任意类型

高级用法:

  • 泛型的上限:
    格式: 类型名称 <? extends 类 > 对象名称
    意义: 只能接收该类型及其子类

  • 泛型的下限:
    格式: 类型名称 <? super 类 > 对象名称
    意义: 只能接收该类型及其父类型
    举个例子:

    public static void main(String[] args) {
    Collection list1 = new ArrayList();
    Collection list2 = new ArrayList();
    Collection list3 = new ArrayList();
    Collection list4 = new ArrayList();

      getElement1(list1);
      getElement1(list2);//报错
      getElement1(list3);
      getElement1(list4);//报错
      
      getElement2(list1);//报错
      getElement2(list2);//报错
      getElement2(list3);
      getElement2(list4);
    

    }
    // 泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类
    // Integer extends Number extends Object
    // String extends Object
    public static void getElement1(Collection<? extends Number> coll){}
    // 泛型的下限:此时的泛型?,必须是Number类型或者Number类型的父类
    public static void getElement2(Collection<? super Number> coll){}

    来个更明显的例子,四个类,如下:

    public class People {
    
        /**
         * 姓名
         */
        private String name;
    
        /**
         * 年龄
         */
        private int age;
    
        public People(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public People() {
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
    
    
    public class Student extends People{
    
        public Student(String name, int age) {
            super(name, age);
        }
    
        public Student() {
        }
    }
    
    public class BasicStudent extends Student{
    
        public BasicStudent(String name, int age) {
            super(name, age);
        }
    
        public BasicStudent() {
        }
    }
    
    public class DemoTest2 {
    
        public static void main(String[] args) {
            ArrayList<People> arrList1 = new ArrayList<>();
    
            //  boolean add(E e)  确保此集合包含指定的元素(可选操作)。
            // 说明add方法可以添加指定对象以及指定对象的子类
            arrList1.add(new Student("迪丽热巴",22));
            arrList1.add(new BasicStudent("邓伦",23));
    
            ArrayList<Student> arrList2 = new ArrayList<>();
            ArrayList<BasicStudent> arrList3 = new ArrayList<>();
            ArrayList<People> arrList4 = new ArrayList<>();
    
            //  boolean addAll(Collection<? extends E> c) 将指定集合中的所有元素添加到此集合(可选操作)。
            // 测试addAll方法
            arrList2.add(new Student("迪丽热巴",22));
            arrList2.add(new Student("邓伦",23));
    
            arrList3.add(new BasicStudent("杨幂",34));
            arrList3.add(new BasicStudent("郑恺威",35));
    
            arrList4.add(new People("杨洋",24));
            arrList4.add(new People("郑爽",23));
    
            // 可以添加成功
            arrList2.addAll(arrList3);
            // 报错,添加失败,原因是addAll方法的参数中通配符有上界的限制,只能添加该类以及该类的子类,不能添加父类等其他类
            // arrList2.addAll(arrList4);
    
            System.out.println(arrList2);
    
    
        }
    }
    

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

    /**
     * 斗地主的测试类
     *  1.买牌
     *  2.洗牌
     *  3.发牌
     *  4.看牌
     *
     * @author WZLOVE
     * @create 2018-07-11 17:36
     */
    public class DDZDemoTest {
    
        public static void main(String[] args) {
    
            // 买牌
            ArrayList<String> poker = new ArrayList<>();
    
            String[] arr1 = {"♠","♥","♣","♦"};
            String[] arr2 = {"2","A","K","Q","J","10","9","8","7","6","5","4","3"};
            for (String s : arr1) {
                for (String s1 : arr2) {
                    poker.add(s + s1);
                }
            }
            poker.add("大王");
            poker.add("小王");
            System.out.println(poker.size());
    
            // 洗牌
            Collections.shuffle(poker);
    
            // 发牌
            ArrayList<String> people1 = new ArrayList<>();
            ArrayList<String> people2 = new ArrayList<>();
            ArrayList<String> people3 = new ArrayList<>();
            ArrayList<String> dipai = new ArrayList<>();
    
            // 自己的思路
            /*for (int i = 0; i < poker.size();) {
                if(i >= 51){
                    dipai.add(poker.get(i++));
                } else{
                    people1.add(poker.get(i++));
                    people2.add(poker.get(i++));
                    people3.add(poker.get(i++));
                }
            }*/
    
    
             // 老师的思路
            for (int i = 0; i < poker.size();i++) {
                if(i >= 51){
                    dipai.add(poker.get(i));
                } else if(i % 3 == 0) {
                    people1.add(poker.get(i));
                }else if(i % 3 == 1) {
                    people2.add(poker.get(i));
                }else if(i % 3 == 2){
                    people3.add(poker.get(i));
                }
            }
            // 看牌
            System.out.println(people1);
            System.out.println(people2);
            System.out.println(people3);
            System.out.println(dipai);
    
        }
    }
    

posted @ 2018-07-12 07:56  庄子游世  阅读(345)  评论(0编辑  收藏  举报