Collection集合及其方法,迭代器,泛型和数据结构(2020.05.09)

摘要:
今天对集合和集合的一些方法做了整理,以及迭代器的使用,一直以来泛型的使用对我来说都是难点,今天终于突破了,最后对数据结构做了一些简单的介绍,但对于java来说,数据结构显得不那么重要(了解原理即可)。

1.Collection

1.1集合概述
  • 集合的作用:

    • 集合是一个容器,可以存储同种类型的多个数据。
  • 集合的特点:

    • 集合的长度是可变的,可以随时给集合增加长度或减少长度。

    • 集合只能存储引用数据类型,不能存储基本数据类型

      存字符串:ArrayList<String> 
      存整数: ArrayList<Integer>   如果要存基本类型必须写出对应的包装类
      
1.2Collection常用方法
方法说明
boolean add(E e)添加方法
void clear()清空集合中的元素
boolean remove(Object e)删除集合中的某个元素
boolean contains(Object obj)判断集合是否包含某个元素
boolean isEmpty()判断集合是否为空
int size()获取集合的长度
Object[] toArray()把集合转成Object[]类型
  • 示例代码:

    public class Demo常用方法 {
        public static void main(String[] args) {
    
            //创建对象
            Collection<String> coll = new ArrayList<>();
    
            //boolean add(E e)   E代表的就是<>里面的类型
            //添加方法
            coll.add("柳岩");
            coll.add("美美");
            System.out.println(coll);
    
            //void clear()
            //清空集合中的元素
            //coll.clear();
    
    
            //boolean remove(Object e)
            //删除集合中的某个元素,如果有多个重复,只会删除第一个
            coll.remove("美美");
    
            //返回的结果是删除成功或失败,但是这个返回值没有使用价值,所以我们一般不需要接受返回值
            //boolean b2 = coll.remove("甜甜");
            //System.out.println(b2);
    
    
            System.out.println(coll);
    
            //boolean contains(Object obj)
            //判断集合是否包含某个元素
            boolean b = coll.contains("柳岩");
            System.out.println(b);       //true
    
    
            //boolean isEmpty()
            //判断集合是否为空,如果集合是空的就会返回true
            boolean b2 = coll.isEmpty();
            System.out.println(b2);     //false
    
    
            //int size()
            //获取集合的长度
            int size = coll.size();
            System.out.println(size);   //1
    
    
            //Object[] toArray()
            //把集合转成Object[]类型
            Object[] arr = coll.toArray();
            //System.out.println(arr);   //数组打印会出现地址值
            System.out.println(Arrays.toString(arr));
    
        }
    }
    

2.Iterator迭代器

2.1迭代器的作用

​ 迭代器是帮助Collection集合遍历元素的。

2.2迭代器如何获取

​ Collection集合有这个方法:

方法说明
Iterator iterator()获取迭代器对象
2.3迭代器常用方法
  • Iterator接口常用的有两个方法:
方法说明
E next()获取集合中的元素
boolean hasNext()判断集合中有没有下一个元素
void remove()删除当前元素
  • 示例代码:

    public class Demo迭代器 {
        public static void main(String[] args) {
    
            //创建对象
            Collection<String> coll = new ArrayList<>();
    
            coll.add("柳岩");
            coll.add("柳岩");
            coll.add("美美");
            coll.add("花花");
            coll.add("蘑菇");
    
            //遍历集合
            //获取迭代器对象
            Iterator<String> it = coll.iterator();
    
            //使用循环获取每一个元素
            /*
                如果有下一个元素,循环里面就是true,就会继续循环获取
                如果没有下一个元素,循环里面就是false,循环就会自动结束
             */
            //快捷键:itit
            while(it.hasNext()){
                String s = it.next();
                System.out.println(s);
            }
    
        }
    }
    
2.4迭代器原理
  • 源码

    public boolean hasNext() {
        //cursor代表指针,默认值是0
        //size代表长度,也就是集合的长度
        return cursor != size;
    }
    
    @SuppressWarnings("unchecked")
    public E next() {
        checkForComodification();
        //记录指针位置
        int i = cursor;
        if (i >= size)
            throw new NoSuchElementException();
        Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length)
            throw new ConcurrentModificationException();
        //让指针向下移动一次
        cursor = i + 1;
        //获取集合中i位置的元素
        return (E) elementData[lastRet = i];
    }
    
2.5迭代器的问题:并发修改异常
  • 异常:

    在迭代器使用的时候,可以会出现一个错误,这个错误叫做并发修改异常

    ConcurrentModificationException
    
  • 产生原因:

    在迭代器遍历集合的时候,如果使用集合对象对集合的长度进行操作(增加或删除元素),就会出现并发修改异常。

  • 代码演示:

    public class Demo并发修改异常 {
    
        public static void main(String[] args) {
            //创建对象
            Collection<String> coll = new ArrayList<>();
    
            coll.add("柳岩");
            coll.add("柳岩");
            coll.add("美美");
            coll.add("花花");
            coll.add("蘑菇");
    
            //遍历集合
            //获取迭代器对象
            Iterator<String> it = coll.iterator();
    
            //使用循环获取每一个元素
            while(it.hasNext()){
                //给集合添加一个元素
                coll.remove("柳岩");   //这里会报错!!!!
                String s = it.next();
                System.out.println(s);
            }
        }
    }
    
  • 解决办法:

    • 添加时出现并发修改异常,现在无法解决。

    • 删除时出现并发修改异常。

      public class Demo并发修改异常 {
      
          public static void main(String[] args) {
              //创建对象
              Collection<String> coll = new ArrayList<>();
      
              coll.add("柳岩");
              coll.add("柳岩");
              coll.add("美美");
              coll.add("花花");
              coll.add("蘑菇");
      
              //遍历集合
              //获取迭代器对象
              Iterator<String> it = coll.iterator();
      
              //使用循环获取每一个元素
              while(it.hasNext()){
      
                  String s = it.next();
                  if(s.equals("柳岩")){
                      //使用迭代器对象删除当前元素
                      it.remove();
                  }
              }
              
              System.out.println("打印集合" + coll);
          }
      }
      
2.6增强for循环
  • 作用:

    ​ 增强for循环也是可以遍历Collection集合和数组

  • 格式:

    for(元素的类型 元素名 : 集合/数组){
        
    }        
    快捷键:iter
    
  • 代码演示

    public class Demo增强for循环 {
        public static void main(String[] args) {
            //创建对象
            Collection<String> coll = new ArrayList<>();
    
            coll.add("柳岩");
            coll.add("柳岩");
            coll.add("美美");
            coll.add("花花");
            coll.add("蘑菇");
    
            //增强for循环
            for(String s : coll){
                System.out.println(s);
            }
        }
    }
    
  • 增强for的特点:

    • 好处在于:
      • 特别简单
    • 缺点在于:
      • 增强for的底层也是迭代器也会出现并发修改异常
      • 不能使用索引

3.泛型

3.1泛型的作用
  • 不使用泛型

    ​ 存的时候可以存任何类型,但是取出来不方便使用

  • 使用泛型

    ​ 规定了要存储的类型,取出来也方便使用

  • 代码演示

    public class Demo泛型的使用 {
        public static void main(String[] args) {
            //创建对象
            Collection coll = new ArrayList();
    
            //添加元素
            coll.add("abc");
            coll.add(123);
            coll.add(3.14);
    
            //遍历
            for (Object o : coll) {
                System.out.println(o);
            }
    
            //使用泛型
            Collection<String> coll2 = new ArrayList<>();
            //添加元素
            coll2.add("abc");
            coll2.add("defg");
            //coll2.add(123);
    
            //遍历
            for (String s : coll2) {
                System.out.println(s);
            }
    
            //使用泛型就规定了集合的存储类型,方便取出元素并使用
        }
    }
    
3.2泛型的定义

​ 在集合中我们是在【使用】泛型,而不是【定义】泛型。

​ 泛型不仅可以在集合中使用,也可以在别的地方使用。

​ 接下来学习自己定义泛型并使用泛型。

1.类上定义泛型
  • 类上定义泛型格式:

    //泛型代表的是某一种引用数据类型
    public class MyArrayList<T> {
        
    }
    
  • 何时确定类型:

    • 在每次创建对象时确定具体的类型。
  • 代码演示:

    //T代表是任意一种引用类型
    public class MyArrayList<T> {
    
        public void add(T t){
        }
    }
    
    
    public class Demo类上定义泛型 {
        public static void main(String[] args) {
            //创建对象
            MyArrayList<String> list = new MyArrayList<>();
            //泛型确定为了字符串类型
            list.add("123");
            //list.add(123);
    
    
            //创建对象
            MyArrayList<Integer> list2 = new MyArrayList<>();
            //泛型确定为了整数类型
            list2.add(123);
            //list2.add("abc");
    
        }
    }
    
    
2方法上定义泛型
  • 方法上定义泛型格式:

    public <T> void method(T t){
    
    }
    
  • 何时确定类型:

    • 在每次调用方法时确定具体类型
  • 代码演示:

    public class AAA {
    
        //方法上定义泛型
        public <T> void method(T t){
        }
    }
    
    public class Demo方法上定义泛型 {
    
        public static void main(String[] args) {
            //创建对象
            AAA a = new AAA();
            //调用方法泛型确定为字符串
            a.method("abc");
            //调用方法泛型确定为整数
            a.method(123);
        }
    }
    
3接口上定义泛型
  • 接口上定义泛型格式:

    //泛型代表某种引用数据类型
    //泛型的定义是在<>写一个大写字母
    public interface MyColl<T> {
    
        void method(T t);
    }
    
  • 何时确认类型:

    • 在定义子类时确定泛型具体的类型
    • 在子类上不确定具体类型,就把接口的泛型变成类上的泛型
  • 代码演示:

    • 在定义子类时确定泛型具体的类型

      public class MyAAA implements MyColl<String>{
      
          //在子类中确定了泛型的具体类型
          @Override
          public void method(String s) {
      
          }
      }
      
    • 在子类上不确定具体类型,就把接口的泛型变成类上的泛型

      public class MyBBB<T> implements MyColl<T> {
      
          //重写父类抽象方法
          @Override
          public void method(T t) {
      
          }
      }
      //接口的泛型变成类的泛型,就遵守类泛型的规则,在创建类的对象时确定具体的类型
      public class Demo接口的泛型 {
      
          public static void main(String[] args) {
              //创建MyBBB对象
              MyBBB<String> mb = new MyBBB<>();
              mb.method("123");
          }
      }
      
3.3泛型通配符
  • 格式:

    <?>				:可以传递任何的泛型类型
    <? extends XXX>	:可以传递XXX以及XXX的子类类型
    <? super XXX>	:可以传递XXX以及XXX的父类类型
    
  • 示例代码:

    import java.util.ArrayList;
    
    public class Demo泛型通配符 {
        public static void main(String[] args) {
            //要求调用下面这个方法
            ArrayList<String> list = new ArrayList<>();
            ArrayList<Integer> list2 = new ArrayList<>();
            ArrayList<Object> list3 = new ArrayList<>();
    
            //method<? extends Object>
            //method(list);
            //method(list2);
            //method(list3);
    
            //method<? super String>
            method(list);
            //method(list2);   报错!
            method(list3);
    
        }
    
    
        //定义方法
        //如果在<?>表示各种泛型类型都能传递, <?>叫做通配符
        //public static void method(ArrayList<?> list){
    
        //}
    
        //<? extends XXX>	:可以传递XXX以及XXX的子类类型
        //public static void method(ArrayList<? extends Object> list){
    
        //}
    
        //<? super XXX>	:可以传递XXX以及XXX的父类类型
        public static void method(ArrayList<? super String> list){
    
        }
    }
    
3.4泛型在开发中的使用

​ 我们绝大多数的时候只是使用泛型,而不是定义泛型。

​ 学完泛型之后也和之前一样,只要在使用集合时和以前一样会用就可以了。

​ 常用:使用泛型3.1 和使用泛型通配符3.3。

​ 对于3.2的定义泛型我们是不需要定义的,学习它是为了大家看源码的时候能看懂。

4.数据结构

4.1栈和队列
栈:

​ 栈是一个线性表结构,只有一个出入口,从同一个口存放数据和移出数据。

​ 特点:先入后出

队列:

​ 队列也是一个线性表,队列有两个开口,从一边存入数据,从另一边取出数据

​ 特点:先入先出

4.2数组和链表
数组:

​ 数组是在内存中开辟的一块连续的内存空间。

​ 特点:增删慢,查询快

链表:

​ 链表在内存中是不连续的内存空间,数据结构有单向链表和双向链表。现在我们介绍单向链表,单向链表的意思就是前一个结点记录后一个结点的位置。

​ 特点:增删快, 查询慢

4.3树
  • 树的介绍

    ​ 在生活中树就是有树根,有树枝有树叶。

  • 二叉树

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

  • 二叉查找树(*)

    1. 左子树上所有的节点的值均小于他的父节点的值

    2. 右子树上所有的节点值均大于他的父节点的值

    3. 每一个子节点最多有两个子树

    二叉查找树的排序:

    ​ 按照【左中右】的方式就能够获取到从小到大排列的元素:

    ​ 10 15 17 20 34 40

  • 平衡二叉树

    • 什么叫平衡
    • 如何保持平衡
  • 红黑树

总结(跟之前一样,需要及的部分做了记号)

Collection
	介绍:
		单列集合的根接口
	常用方法【记】
		size():获取集合的长度
		add():添加元素
		remove():删除某一个元素
		isEmpty():判断集合是否为空
		contains():判断集合是否包含某个元素
		clear()	:清空集合
		toArray():把集合转成Object[]类型
		iterator():使用集合获取迭代器对象
		
两种遍历方式
	迭代器Iterator【理解并记住】
	
		hasNext():判断有没有下一个元素
		next():获取下一个元素
		remove():删除当前元素
		
	增强for【理解并记住】
	
	并发修改异常【理解】
		产生原因:
			在迭代器遍历的同时,使用集合对元素进行增删,就会出现并发修改异常。
		解决办法:
			不要在遍历的同时增加元素。
			如果要删除元素可以使用迭代器对象调用remove()。
			
泛型
	要会在集中中使用泛型【理解】
	
	定义泛型【了解】
		在类上定义泛型
		在方法上定义泛型
		在接口上定义泛型
		
	泛型通配符
		<?>	:可以接受任何类型【不常见】
		<? extends XXX> :可以接受XXX和XXX的子类类型,泛型的上限。【常见】
		<? super XXX>   :可以接受XXX和XXX的父类类型,泛型的下限。【常见】
		
数据结构【理解并记】
	栈
		先进后出
	队列
		先进先出
	数组
		增删慢,查询快
	链表
		增删快,查询慢
	二叉查找树
		可以对元素进行大小排序
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值