Skip to content

day06 【集合】

今日内容介绍

java
对象数组
Collection接口
迭代器
数据结构
List接口
斗地主案例

第零章 回顾

集合怎么使用

java
//创建集合对象
ArrayList<String> list = new ArrayList<>();
//添加数据到集合中
list.add("迪迦");
list.add("赛文");
// 遍历集合
for(int i = 0;i<list.size();i++){
    String s = list.get(i);
    System.out.println(s);
}

集合的操作套路

java
1:创建容器对象
2: 添加元素到集合对象中
3: 遍历集合

多态

多态是什么?父引用指向子类对象。

**在多态下的一些特点 **

java
public abstract class Animal{

    public abstarct void eat();

}

public class Cat extends Animal{
    public void eat(){
        System.out.println("猫吃鱼");
    }

    public void play(){
       System.out.println("猫玩毛线");
    }
}

在多态下 写代码
Aniaml a = new Cat();
外表是 Animal
a能调用的功能 是什么?
    只能调用父引用类型中定义的方法!!
    子类特有功能 ,对不起,不能调用。
如果我们要研究一个抽象类或者一个接口中的方法,
可不可以采用多态形式!!!
   可以!!
 研究动物吃
   Aniaml a = new Cat();
  a.eat()
      注意 所有动物都会玩吗?

第一章 Collection 集合【重点】

1.1 集合与数组的区别

java
集合和数组的区别?
1.相同点
    都是引用类型,都是容器,都可以存储对象。
2.区别
   数组是定长的,一旦定义长度不可变。
   集合是不定长的,可以扩容。
   数组可以存储基本类型。

1627529937047

1.2 Collection 集合体系

1627529953354

1.3 Collection 集合中的常用方法

java
java.util.Collection<E>接口:
    常用方法:
        public boolean add(E e) : 把给定的对象添加到当前集合中 。
        public boolean addAll(Collection con):
			把方法参数集合对象con中的所有元素添加到调用方法的集合对象中

        public void clear() :清空集合中所有的元素。
        public boolean remove(E e) : 把给定的对象在当前集合中删除。
            有相同元素,只能删除一个

        public boolean contains(Object obj) : 判断当前集合中是否包含给定的对象。
        public boolean isEmpty() : 判断当前集合是否为空。
        public int size() : 返回集合中元素的个数。
        public Object[] toArray() : 把集合中的元素,存储到数组中。
java
package com.itheima.collection01;

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

public class CollectionDemo01 {
    /*
    Collection 单列集合顶层接口,里面定义了所有单列集合应该具备功能
                                     功能都只有声明,需要具体的子类去实现。
                             Collection<E>  ArrayList<E>
                             E 泛型 当前你创建对象的时候 会用具体的类型替换掉E
                     add(E e);  E是泛型 代表你想传什么就是什么

                     boolean isEmpty()如果集合里面没元素就是true 有元素就是false
                    int size(); 查看 集合中有几个元素
                    添加元素到集合  boolean add(E e)  添加成功是true  不成功false
                    boolean contains(Object obj)  判断指定元素是否在集合中
                    boolean remove(Object obj)  删除指定元素 返回删除成功与否
                    清空集合操作 void clear()
     */
    public static void main(String[] args) {
        /*怎么去研究 Collection中的方法?
         * 能直接 new Collection吗? 不行
         *    使用多态形式  父引用 指向子类对象
 6        *      因为 多态下 只能 调用 父接口 里面定义的功能
         */
        // 创建集合对象
        Collection<String> collection = new ArrayList<>();
        // 研究里面定义的方法
       // boolean isEmpty()如果集合里面没元素就是true 有元素就是false
        System.out.println("查看集合是否为空:"+collection.isEmpty());
        // int size(); 查看 集合中有几个元素
        System.out.println("当前集合中有"+collection.size()+"个元素");
        // 添加元素到集合  boolean add(E e)  添加成功是true  不成功false
        System.out.println(collection.add("薇娅"));
        collection.add("张庭");
        System.out.println("当前集合中有"+collection.size()+"个元素");
        // 集合中 有没有 葫芦娃
        // boolean contains(Object obj)  判断指定元素是否在集合中
        System.out.println("当前集合有没有葫芦娃:"+collection.contains("葫芦娃"));
        System.out.println("当前集合有没有薇娅:"+collection.contains("薇娅"));
       // 从集合 删除元素   boolean remove(Object obj)  删除指定元素 返回删除成功与否
        System.out.println("从集合删除葫芦娃:"+collection.remove("葫芦娃"));
        System.out.println("从集合删除薇娅:"+collection.remove("薇娅"));
        System.out.println("当前集合中有"+collection.size()+"个元素");
        // 清空集合操作 void clear()
        collection.clear();
        System.out.println("查看集合是否为空:"+collection.isEmpty());

    }
}

第二章 迭代器

2.0 为什么 Collection 集合形式下 不能进行 fori

java
package com.itheima.collection01;

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

public class CollectionDemo2 {
    public static void main(String[] args) {
        //创建一个集合对象
        Collection<String> collection = new ArrayList<>();
        //添加几个元素
        collection.add("尼古拉斯赵四");
        collection.add("刘能");
        collection.add("谢广坤");
        collection.add("王老七");

        //遍历元素?
//        for(int i = 0;i<collection.size();i++){
//            // 在编译阶段  这里爆了红色问题  为什么?
//          // String s =  collection.get(i);//因为没有该方法 这个方法属于 子类的方法  跟父接口Collection没关系
//            // 不能用  官方说 一些 collection 是有序的,而另一些则是无序的。
//                      // get(index)根据 元素的索引找元素  注意元素如果有索引说明集合是有序的!!
//
//
//        }
        // fori 这种遍历方式  针对Collection整体而言是不行的,只能针对有序的集合。
    }
}

原因:Collection 里面既有有序的又有无序的,而 get 只能操作有序的集合,故而该接口中没有 get 方法。

所以 fori 在 Collection 集合 单列集合这里不是通用的。

既然之前学的 fori 不是通用的 那么对于 Collection 有没有通用的遍历方式,有!!借助外力,使用一个工具叫:迭代器。 帮助我们完成 Collection 集合的遍历。

2.1 迭代器的基本使用

Collection 有个方法 可以获取迭代器

java
Iterator<E> iterator();获取迭代器

迭代器 是一个工具,需要集合对象 叫出来(调用出来),注意每次调用 collection.iterator()都是给你新的迭代器!

这个工具,是用来帮助我们遍历集合。 迭代器中有

next()功能

java
 E next()方法  通过迭代器遍历我们的元素
   注意 这个方法 每次获取完之后指向下一个元素  再获取就是下一个元素

   如果没法获取元素 会出现一个异常  NoSuchElementException
java
package com.itheima.collection01;

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

public class CollectionDemo3 {
    public static void main(String[] args) {
        //创建一个集合对象
        Collection<String> collection = new ArrayList<>();
        //添加几个元素
        collection.add("尼古拉斯赵四");
        collection.add("刘能");
        collection.add("谢广坤");
        collection.add("王老七");
      // 无法fori 只能通过迭代器
        // 迭代器 怎么用能
        // 呼叫出来迭代器
        // 怎么呼叫 调用方法  iterator()方法  每个Collection集合都有独立的 迭代器
        Iterator<String> iterator = collection.iterator();
        // iterator 迭代器 就是来帮我们完成遍历的工具
        // 使用迭代器的 E next()方法 可以获取我们集合中元素
        String next1 = iterator.next();
        System.out.println(next1);
        // 再想获取  再调用一次
        String next2 = iterator.next();
        System.out.println(next2);
        //  next功能有什么特点  获取一个之后  再调用 获取下一个
        String next3 = iterator.next();
        System.out.println(next3);
        String next4 = iterator.next();
        System.out.println(next4);

        String next5 = iterator.next();// 总共四个元素  你调用5次next 爆出了 NoSuchElementException
        System.out.println(next5);
    }
}

2.2 如何再遍历的时候 ,避免 NoSuchElementException 异常

java
iterator.hasNext() 有没有下一个元素  有就进到循环里面 去获取
        如果没有 就结束
        先做判断  有就获取 没有就结束
java
package com.itheima.collection01;

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

public class CollectionDemo4 {
    public static void main(String[] args) {
        //创建一个集合对象
        Collection<String> collection = new ArrayList<>();
        //添加几个元素
        collection.add("尼古拉斯赵四");
        collection.add("刘能");
        collection.add("谢广坤");
        collection.add("王老七");
      // 无法fori 只能通过迭代器
        // 迭代器 怎么用能
        // 呼叫出来迭代器
        // 怎么呼叫 调用方法  iterator()方法  每个Collection集合都有独立的 迭代器
        Iterator<String> iterator = collection.iterator();
        // iterator 迭代器 就是来帮我们完成遍历的工具
        //可不可以将代码进行优化
        // 1:重复代码放到循环中
        // 2:不知道遍历几次 用while循环
        while(iterator.hasNext()){//这里的判断怎么写?
            // 获取 集合中元素  有元素才获取 iterator.hasNext() 有没有下一个元素
            String next = iterator.next();
            System.out.println(next);
        }
    }
}

总结 如何使用迭代器完成的遍历

java
1:通过集合对象得到遍历工具 迭代器   Iterator<String> iterator = collection.iterator();
2:写一个while循环
  while(iterator.hasNext()){ //先判断有没有下一个可以被遍历的元素
     // 有 就获取
    String next=  iterator.next();//这里next只能调用一次
     next就是被遍历出来的元素。
  }

练习: 集合存储自定义类型并遍历

java
//创建标准的学生Student类
public class Student {
    private String name;
    private int age;
    //覆盖重写toString方法
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
	//空参/满参,set和get
}
java
package com.itheima.collection01;

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

public class CollectionTest {

    public static void main(String[] args) {
        //创建 Collection对象   存储的自定义类型
        Collection<Student> collection = new ArrayList<>();
       // 存储 三个学生对象到该集合
        Student wyf = new Student("吴亦凡", 32);
        Student hhb = new Student("黄海波", 46);
        Student lzx = new Student("罗志祥", 43);

        collection.add(wyf);
        collection.add(hhb);
        collection.add(lzx);
        // 遍历该集合  输出每个学生对象的名字
        //先获取迭代器
        Iterator<Student> it = collection.iterator();
        // 判断该位置有没有可以获取的元素
        while(it.hasNext()){
            // 如果有   就获取
            Student student = it.next();//获取到当前位置的元素  指针指向下一个了
            System.out.println(student.getName());
        }

    }
}

2.3 迭代器的原理

1641093142371

1641093173824

2.5 并发修改异常--了解即可(面试内容)

java
package com.itheima.collection01;

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

public class CollectionDemo5 {
    public static void main(String[] args) {
        // 创建了一个集合对象  a  b  b  c  d
        Collection<String> arrayList = new ArrayList<>();
        arrayList.add("a");
        arrayList.add("b");
        arrayList.add("b");
        arrayList.add("c");
        arrayList.add("d");
        // 在获取迭代器之前  集合5个元素

        Iterator<String> iterator = arrayList.iterator();
        // 迭代器 感知的集合 里面是  5个元素

        while(iterator.hasNext()){
            String next = iterator.next();
            if(next.equals("b")){
               arrayList.remove("b");// 集合对象删除了b.没有通知迭代器
                                    //集合中元素的个数  4
                                   // 迭代器感知的是  5
                                 // 并发修改  ---迭代器在进行迭代
                                         //  --- 集合修改了长度
            }
        }
        System.out.println(arrayList);
    }
}

1641094654865

观察以上代码,说出运行结果?并解释原因

java
该代码 会爆出一个异常 ConcurrentModificationException
      并发修改异常--就是错误的操作方式。
 arrayList.remove("b");//集合对象   删除元素  是不是就改变了 集合中元素的个数(集合长度)
 在java中 使用迭代器遍历集合元素,那么集合对象不能修改集合的长度。
 如果修改了,就容易出现 并发修改异常。


原因:

1641095014745

使用迭代器遍历的时候,就不能修改集合的元素了吗?

java
可以修改,但是 迭代器与集合要同步好 元素的个数
  集合改完了会不会同步给迭代器,不会。
  但是  迭代器修改了 会同步给集合。
  通过迭代的方法。
java
 if(next.equals("b")){
     // arrayList.remove("b");//集合对象   删除元素  是不是就改变了 集合中元素的个数(集合长度)
     iterator.remove();//删除当前遍历的元素,并同步给集合
 }

结论:

java
使用迭代器遍历元素的时候,就不要进行元素的添加和删除了!!!

第三章 增强 for

write less do more 写的少 做的多。

格式:

java
   for(类型 变量名:被遍历的集合或数组){
       // 变量名 是用来接收  被遍历出来的每一个元素的。
   }

作用:简化迭代器的遍历。

底层是迭代器,但是我们不用关注 Iterator 也不用关注 hasNext() next() 只需要关注格式!!

1641095561313

1641095654033

java
package com.itheima.foreach;

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

public class ForEachDemo {
    public static void main(String[] args) {
        // 创建了一个集合对象  a  b  b  c  d
        Collection<String> arrayList = new ArrayList<>();
        arrayList.add("a");
        arrayList.add("b");
        arrayList.add("b");
        arrayList.add("c");
        arrayList.add("d");
        /*
        增强for
         */
        for(String s :arrayList){
            System.out.println(s);
        }


    }
}

第四章 List 集合及其子类

1641105036964

4.1 List 集合特点

1641105871293

java
List是有序(存取顺序一致),因为有序,所以有索引。
   实现类主要是保证元素的存取顺序一致,不关心是否有重复元素。
   它特有的功能一定是跟索引相关。
特点
   有序、有索引、可重复

1641106115256

java
Set集合里面的元素是唯一的,不允许出现e1 e2 的equals的值是true,null值只能是一个。
特点
  唯一:集合里面的元素不重复的。
  无序:不保证存取顺序一致。
  没有索引。

4.2 List 集合特有方法

1641105082823

java
package com.itheima.list;

import java.util.ArrayList;
import java.util.List;
/*
       List体系中特有的功能
          add(int index,E e) 往指定索引位置 插入元素
          E get(int index) 根据索引获取元素
          E set(int index,E e)  在指定位置 设置一个新的值 返回一个被替换的值
          E remove(int index) 根据索引删除元素   返回值是被删除的元素
 */
public class ListDemo {
    public static void main(String[] args) {
        //研究List集合
        List<String> list = new ArrayList<>();
        // 添加元素
        list.add("周杰伦");
        list.add("张艺兴");
        list.add("王宝强");
        System.out.println(list);//存取顺序一致
        //  add(int index,E e) 往指定索引位置 插入元素
        list.add(1,"乔杉");
        System.out.println(list);
        // E get(int index) 根据索引获取元素
        String s = list.get(1);
        System.out.println(s);
        // E set(int index,E e)  在指定位置 设置一个新的值 返回一个被替换的值
        String s1 = list.set(1, "胡歌");
        System.out.println("set的返回值:"+s1);

        System.out.println("当前集合的顺序:"+list);
        // E remove(int index) 根据索引删除元素   返回值是被删除的元素
        String remove = list.remove(1);
        System.out.println("被删除的元素:"+remove);

        System.out.println("当前集合中的元素:"+list);
    }
}

4.3 数据结构

概念:数据存储在内存中的方式。

研究什么,看一看有哪些存储方式,它们的特点是什么?

java
栈模型
  出口入口在一端,另一端封闭。
名词
 压栈:元素进入栈模型。
 弹栈:元素离开栈模型。
元素的特点:
   先进后出,后进先出。
应用场景
  子弹夹、java中方法入栈。

1641107559484

队列

java
队列模型
   有两端,入口一端,出口一端
名词
   入队列 从后(入口)端进到队列模型中。
   出队列 从前(出口)端离开队列模型。
元素特点
   先进先出,后进后出
应用
  排队打针,消息队列,秒杀队列

1641107788832

数组 一块连续的空间

java
数组结构
   一段连续的空间结构,每个元素都有索引,而且是挨着的。
特点
  查询快   因为连续且有索引,找每个元素的时间是相同的。
  增删慢   增加或者删除都会改变数组的结构,需要重新构建并且复制元素。

1641108291807

链表 手拉手这种

java
链表结构
   数据是分散存储的,上一个元素都有下一个元素地址值。
特点
  增删快
     只需要进行局部修改就能完成增删。
  查询慢
     查询的时候需要从头找起。

1641108681856

4.4 数组结构集合 ArrayList

ArrayList 和 LinkedList 有什么区别?--面试题

java
它们都是List集合,都有索引,它们都能保证存取顺序一致。
ArrayList集合特点:它是数组结构的,查询快,增删慢。它是线程不安全的,所以效率高。
LikedList集合特点:它是链表结构的,查询慢,增删快。它是线程不安全的,所以效率高。
---Vector 集合
    它是数组结构,查询快,增删慢。它是线程安全,效率低。

ArrayList 代码演示略。

4.5 链表结构集合 LinkedList

1641110251377

java
package com.itheima.list;

import java.util.LinkedList;

public class LinkedListDemo {
    public static void main(String[] args) {
        LinkedList<String> list = new LinkedList<>();

        list.add("乔布斯");
        list.add("古天乐");
        list.add("科比");

        System.out.println("集合中的结构:"+list);//[乔布斯, 古天乐, 科比]

        list.addFirst("c罗");//在链表的头部位置添加元素
        System.out.println("集合中的结构:"+list);
        list.addLast("梅西");
        System.out.println("集合中的结构:"+list);

        System.out.println("获取头部元素:"+list.getFirst());
        System.out.println("集合中的结构:"+list);

        System.out.println("删除头部元素:"+list.removeFirst());
        System.out.println("集合中的结构:"+list);

        System.out.println("弹栈方法:"+list.pop());
        System.out.println("集合中的结构:"+list);

    }
}

第五章 总结及斗地主案例

5.1 Collection 单列集合--List 集合---ArrayList LinkedList

java
Collection 单列集合的顶层接口
     里面定义了单列集合都包含的功能
     add(E e)
     remove(E e)
     isEmpty()
     size()
     clear()
     contains()
     toArray() 把集合转换成数组
如何进行单列集合的通用遍历--迭代器
    colliection.iterator()返回一个迭代器对象Iterator<泛型>
    迭代器有什么功能
     hasNext()判断当前位置有没有可以遍历的元素
     next() 获取当前位置元素,并指向下一个
    while(iterator.hasNext()){
        iterator.next();
    }
    比较麻烦
增强for
    for(类型 变量名:被遍历的容器){}
    集合对象.for
    它是 迭代器的简化形式。
    记住 我们在使用迭代遍历的时候,仅仅为遍历,不建议去修改集合。
         因为 如果在用迭代器遍历过程中,修改了 集合中长度,那么会出现兵法修改异常。
List集合
   特点 元素存取顺序一致 可以存储重复元素 有索引
   它的特有功能跟索引相关
       add(int index,E e)指定位置添加元素
       set(int index,E e)指定位置修改指定元素
       get(int index)获取指定位置元素
       remove(int index)删除指定位置元素
四种数据结构
    栈 先进后出
    队列 先进先出
    数组  查询快 增删慢
    链表  查询慢 增删快
List的子类
    ArrayList LinkedList 区别参考上面内容

List集合有几种遍历方式?
   普通的迭代器
   增强for
   fori的形式(索引形式)

  如果仅仅是查看元素  用增强for。
  如果你还想修改元素  使用fori。

5.2 斗地主案例

分析:

1641114754781

代码:

java
package com.itheima.poker;

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

public class Poker {
    public static void main(String[] args) {
        /*
        1:准备牌
         1.1 创建一个ArrayList集合 pokerList
         1.2 创造54张牌
            花色 ♠  ♣  ♥ ♦
            数字 2-10 J Q K A
            大♛  小♚
            1.2.1 先把 大王小王存到集合中
            1.2.2 构建另外52张牌
               花色+数字组成
               每一个花色 和 每一个数字 拼接
               准备花色集合 ♠  ♣  ♥ ♦
               准备数字集合 2-10 J Q K A
           1.2.3
              先遍历花色 得到每个花色
                再遍历数字 每个花色+数字 拼接 形成了牌面
           1.2.4     把 牌面存储到扑克集合中
         */
        //1:准备牌
        // 1.1 创建 牌盒
        ArrayList<String> pokerList = new ArrayList<>();
        //1.2 创造牌
        //1.2.1  完成大小王的存储
        pokerList.add("大♛");
        pokerList.add("小♚");
        // 1.2.  构建另外52张牌
        // 1.2.2 创建两个集合
        // 花色集合
        ArrayList<String> colors = new ArrayList<>();
        //数字集合
        ArrayList<String> numbers = new ArrayList<>();
        //存花色
        colors.add("♠");
        colors.add("♣");
        colors.add("♥");
        colors.add("♦");

        // 2~10
        for (int i = 2; i <=10 ; i++) {
            numbers.add(i+"");//基本类型变为字符串
        }
        //存数字
        numbers.add("J");
        numbers.add("Q");
        numbers.add("K");
        numbers.add("A");
        // 1.2.3 遍历 花色和数字
        for (String color : colors) {
            //color就是一种花色
            for (String number : numbers) {
                //number就是数字
                //1.2.4 拼接牌面
                String card = color+number;
                //牌面存储到 牌盒中
                pokerList.add(card);
            }
        }

        System.out.println("洗牌之前"+pokerList);
      /*
      2:洗牌
        就是打乱集合中元素的顺序
           工具类 Collections.shuffle(list集合)
       */
        Collections.shuffle(pokerList);
        System.out.println("洗牌后:"+pokerList);

        /*
        3:发牌
           3.1 创建四个集合 三个玩家 一个底牌集合
           3.2 发牌 采用fori 因为需要索引进行判断发牌
               采用 fori的形式 遍历牌盒
               怎么去发  ?
               根据索引发牌面
                 先获取 当前索引对应的牌面
                 再决定这张牌 发给谁。
                   通过 i索引的判断
                       留底牌  i>=51
                          对 3 取余
                             0  发给 UZI
                             1  发给 LBW
                             2  发给 PDD
         */
//        3.1 创建四个集合 三个玩家 一个底牌集合
        ArrayList<String> uzi = new ArrayList<>();
        ArrayList<String> lbw = new ArrayList<>();
        ArrayList<String> pdd = new ArrayList<>();
        ArrayList<String> dipai = new ArrayList<>();

        // 3.2 遍历牌盒
        for (int i = 0; i < pokerList.size(); i++) {
            //先获取牌面
            String card = pokerList.get(i);
            //再发牌
            //先留出底牌
            if(i>=51){
                //牌面给底牌集合
                dipai.add(card);
            }else if(i%3==0){//索引3取余 0 给uzi
                //玩家一
                uzi.add(card);
            }else if(i%3==1){//索引3取余 0 给lbw
                //玩家er
                lbw.add(card);
            }else{
                pdd.add(card);
            }
        }

        // 4:查看牌
        System.out.println("简自豪:"+uzi);
        System.out.println("卢本伟:"+lbw);
        System.out.println("刘谋:"+pdd);
        System.out.println("底牌:"+dipai);
    }
}

Released under the MIT License.