迭代器(增强for循环),泛型,数据结构

Iterator迭代器

迭代的概念

迭代:即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续再判断,如果还有就再取出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。
获取迭代器对象
Collection集合提供了一个获取迭代器的方法:
public Iterator iterator()`: 获取集合对应的迭代器,用来遍历集合中的元素的
Iterator接口的常用方法

  • public E next()`:返回迭代的下一个元素。
  • public boolean hasNext():如果仍有元素可以迭代,则返回 true。
    案例演示
 public class Test {
    public static void main(String[] args) {
        /*
            - 迭代的概念
                概述: Collection集合获取元素通用的方式。在获取元素之前要先判断集合中是否有元素可以获取,如果有,
                     就把这个元素取出来,接下来继续判断,如果还有,就继续取出来,直到把集合中所有元素取出来为止,这就
                     是迭代
            - 获取迭代器对象
                1.迭代器对象:Iterator接口对象
                2.如何获取集合对应的迭代器对象
                  使用Collection集合中的iterator()方法:
                        Iterator<E> iterator();获取集合对应的迭代器对象

            - Iterator接口的常用方法
                    boolean hasNext() 判断集合中是否有元素可以迭代
                    E next()  获取集合中的元素
         */
        // 创建一个Collection集合,限制集合中元素的类型为String
        Collection<String> col = new ArrayList<>();
        // 添加元素
        col.add("范冰冰");
        col.add("李冰冰");
        col.add("高圆圆");
        col.add("刘诗诗");
        // 迭代
        // 获取该集合对应的迭代器对象
        Iterator<String> it = col.iterator();

        // 使用while循环,判断集合中是否有元素可以获取
        while (it.hasNext()) {
            // 如果有,就取出来
            String e = it.next();
            System.out.println(e);
        }
    }
}

常见问题一
在进行集合元素获取时,如果集合中已经没有元素可以迭代了,还继续使用迭代器的next方法,将会抛出java.util.NoSuchElementException没有集合元素异常。
常见问题二
在进行集合元素迭代时,如果添加或移除集合中的元素 , 将无法继续迭代 , 将会抛出ConcurrentModificationException并发修改异常.

迭代器的实现原理
Iterator迭代器对象在遍历集合时,内部采用指针的方式来跟踪集合中的元素。在调用Iterator的next方法之前,迭代器的索引位于第一个元素之前,不指向任何元素,当第一次调用迭代器的next方法后,迭代器的索引会向后移动一位,指向第一个元素并将该元素返回,当再次调用next方法时,迭代器的索引会指向第二个元素并将该元素返回,依此类推,直到hasNext方法返回false,表示到达了集合的末尾,终止对元素的遍历。

增强for

是for循环中增强的方法,高级for循环,专门用来遍历数组和集合的,内部原理其实是个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。
格式:
for(元素的数据类型 变量 : Collection集合or数组){
//写操作代码
}
特别注意:
1.增强for循环必须有被遍历的目标,目标只能是Collection集合或者是数组,与Map双列集合无关;
2.Collection是所有单列集合的根接口,如果要对单列集合进行遍历,通用的遍历方式是迭代器遍历或增强for遍历。
3.增强for(迭代器)仅仅作为遍历操作出现,不能对集合进行增删元素操作,否则抛出ConcurrentModificationException并发修改异常

泛型

泛型的概述:
泛型是为了方便安全集合储存数据,控制未知数据类型而服务的
泛型的作用:
使用泛型在编译期直接对集合的数据类型做出了控制,指定储存的数据类型,如果不使用泛型,集合存进去什么类型都能存,取出来时啥也不是,报异常。

泛型通配符
泛型通配符:不知道使用什么类型来接收的时候,此时可以使用?,?表示未知通配符。

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

泛型的上限:**

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

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

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);
  
}
// 泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类
public static void getElement1(Collection<? extends Number> coll){}
// 泛型的下限:此时的泛型?,必须是Number类型或者Number类型的父类
public static void getElement2(Collection<? super Number> coll){}

数据结构

数据结构 : **其实就是存储数据和表示数据的方式,常见的数据结构:堆栈、队列、数组、链表和红黑树 .

栈**:stack,又称堆栈,它是运算受限的线性表,其限制是仅允许在表的一端进行插入和删除操作,不允许在其他任何位置进行添加、查找、删除等操作

例如,子弹压进弹夹,先压进去的子弹在下面,后压进去的子弹在上面,当开枪时,先弹出上面的子弹,然后才能弹出下面的子弹。
注意:
1.栈先进后出(即,存进去的元素,要在后它后面的元素依次取出后,才能取出该元素)
2.栈的入口、出口的都是栈的顶端位置**。
3.压栈**:就是存元素。即,把元素存储到栈的顶端位置,栈中已有元素依次向栈底方向移动一个位置。
4.弹栈:就是取元素。即,把栈的顶端位置元素取出,栈中已有元素依次向栈顶方向移动一个位置。

**

队列

队列**:queue,简称队,它同堆栈一样,也是一种运算受限的线性表,其限制是仅允许在表的一端进行插入,而在表的另一端进行取出并删除。

对元素存取特点:
1.先进先出**(即,存进去的元素,要在后它前面的元素依次取出后,才能取出该元素)。例如,小火车过山洞,车头先进去,车尾后进去;车头先出来,车尾后出来。
2.队列的入口、出口各占一侧。**例如,下图中的左侧为入口,右侧为出口。

数组
数组**:Array,是有序的元素序列,数组是在内存中开辟一段连续的空间,并在此空间存放元素。就像是一排出租屋,有100个房间,从001到100每个房间都有固定编号,通过编号就可以快速找到租房子的人。

数组特点:
1.查询块
(通过索引,可以快速访问指定位置的元素)
2.增删慢
(1.增加需要创建一个新数组,将指定新元素存储在指定索引位置,再把原数组元素根据索引,复制到新数组对应索引的位置;
2.指定索引位置删除元素需要创建一个新数组,把原数组元素根据索引,复制到新数组对应索引的位置,原数组中指定索引位置元素不复制到新数组中)
数组特点六个字:查询块,增删慢。

链表

链表:由一系列结点node(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。我们常说的链表结构有单向链表与双向链表

二叉树

如果树中的每个节点的子节点的个数不超过2,那么该树就是一个二叉树。

二叉查找树
二叉查找树的特点:

  1. 左子树上所有的节点的值均小于等于他的根节点的值
  2. 右子树上所有的节点值均大于或者等于他的根节点的值
  3. 每一个子节点最多有两个子树

平衡二叉树
规则:**它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树

红黑树

红黑树是一种自平衡的二叉查找树
红黑树的特性:

  1. 每一个节点或是红色的,或者是黑色的。
  2. 根节点必须是黑色
  3. 每个叶节点(Nil)是黑色的;(如果一个节点没有子节点或者父节点,则该节点相应的指针属性值为Nil,这些Nil视为叶节点)
  4. 如果某一个节点是红色,那么它的子节点必须是黑色(不能出现两个红色节点相连的情况)
  5. 对每一个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值