当前位置: 移动技术网 > IT编程>开发语言>Java > 荐 Collection集合,Iterator迭代器,<>泛型

荐 Collection集合,Iterator迭代器,<>泛型

2020年07月16日  | 移动技术网IT编程  | 我要评论

Collection

集合概述:

集合作为容器用来存储,管理大量的对象(引用),这些集合内部cc爱用了不同的数据结构来存储元素,这些数据结构的不同导致了每种集合的增删改查效率不同。
数据结构会另开一篇。
Java常用集合体系:
在这里插入图片描述

Collection接口的常用方法

由于Collection是一个接口,所以该类中全部都是抽象方法,调用时会使用多态(父类型引用指向子类型对象)。主要了解这些方法的作用。

增:

public boolean add(E e);//把给定的对象添加到集合中

删:

  1. public void clear();//清空集合中所有元素。
  2. public boolean remove(E e);//把给定的对象在集合中删除

改:【无】

查:

  1. public boolean contains(Object obj);//判断当前集合是否包含给定元素
  2. public boolean isEmpty();//判断集合是否为空
  3. public int size();//返回当前集合元素的个数。
  4. public Object[] toArray();//把集合中的元素储存在数组中。
  5. public Iterator iterator();//获取一个迭代器,用于遍历集合元素
代码演示:
package Collection集合的增删改查Test;

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

public class Demo01 {
    public static void main(String[] args) {
        //多态,父类型引用指向子类型对象

        Collection<String> list = new ArrayList<String>();
        //增:
        //调用子类ArrayList重写的add方法:向集合中添加元素
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("赵六");
        list.add("冯七");
        for (String s:list) {
            System.out.println(s);
        }
        //删:
        //clear()删除集合中所有元素:
        //list.clear();
        System.out.println(list.size());
        //remove(E e):将给定的元素在集合中删除。返回boolean值
        list.remove("张三");
        System.out.println("移除后元素有:");
        for(String s:list){
            System.out.println(s);
        }
        //改【无】
        //查:
        //contains(Object obj):查询给定元素是否存在集合中,返回boolean
        boolean boo = list.contains("李四");
        System.out.println(boo);
        //isEmpty():判断集合是否为空,返回boolean;
        boo = list.isEmpty();
        System.out.println(boo);
        //size()返回集合中元素的个数:
        int sum = list.size();
        System.out.println(sum);
        //toArray():把集合元素储存在数组中;返回一个Object[]数组
        Object[] obj = list.toArray();
        for (int i = 0; i <obj.length ; i++) {
            System.out.println(obj[i]);
        }
    }
}

迭代器Iterator

Collection中定义了一个遍历元素的方法:
public Iterator iterator();此方法可以获取一个迭代器,用于遍历集合元素。

代码演示
package iterator迭代器;

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

public class Demo01 {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<String>();
        //增:
        //调用子类ArrayList重写的add方法:向集合中添加元素
        list.add("郭德纲");
        list.add("柳岩");
        list.add("成龙");
        list.add("洪金宝");
        //调用集合的iterator方法获取迭代器。
        Iterator<String> it = list.iterator();
        //调用迭代器Iterator<>中的hasNext判断集合中是否还存在元素。返回boolean值
        while(it.hasNext()){
            //调用next方法遍历集合中的元素。
            System.out.println("获取一个元素"+it.next());
        }

    }
}
图解代码:

在这里插入图片描述

注意!!!

这个“迭代器”是“单向”的,只能从上到下。而且是“一次性”的。
如果想再次使用迭代器,就需要再次调用集合的iterator()方法,获取一个新的迭代器。

迭代器常见问题

一次hasNext(),然后多次next()----错误

代码演示:
package iterator迭代器;

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

public class Demo01 {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<String>();
        //增:
        //调用子类ArrayList重写的add方法:向集合中添加元素
        list.add("郭德纲");
        list.add("柳岩");
        list.add("成龙");
        list.add("洪金宝");
        //调用集合的iterator方法获取迭代器。
        Iterator<String> it = list.iterator();
        //调用迭代器Iterator<>中的hasNext判断集合中是否还存在元素。返回boolean值
        while(it.hasNext()){
            //调用next方法遍历集合中的元素。
            String str = it.next();
            //不要再次使用next(),这样会导致输出结果不完整。
            System.out.println("获取一个元素"+it.next());
        }
        /*
        运行结果:
                获取一个元素柳岩
                获取一个元素洪金宝
                */

    }
}

并发修改异常:

代码演示:
	public class Demo03 {
    public static void main(String[] args) {
        //1.创建一个集合对象
        Collection<String> list = new ArrayList<>();

        list.add("郭德纲");//modCount++
        list.add("柳岩");//modCount++
        list.add("成龙");//modCount++

        //2.获取迭代器
        Iterator<String> it = list.iterator();
        //3.遍历迭代器
        while (it.hasNext()) {//cursor != size
            String s = it.next();//next()-->调用:checkForComodification(){ modCount != expectedModCount}
//            System.out.println(it.next());//不要再次调用it.next()
            System.out.println(s);
            if (s.equals("成龙")) {
                //删除这个元素
                //list.remove(s);//modCount++当通过迭代器	遍历时,使用"集合对象"删除元素,会引发:并发修改异常。
                //可以通过"迭代器"对象去删除
                it.remove();//OK的
            }
        }
        System.out.println(list);//[郭德纲, 柳岩]

        //作业:当删除倒数第二个元素时,不会抛异常,请问为什么??????
    }
}

增强for循环

  1. 增强for是一个新语法(JDK1.5开始),用于代替某种情况下的普通for循环,语法更加简洁。
    可以遍历:数组、集合

    语法格式:
    for(数据类型 变量名 : 数组名/集合名){
    //直接使用“变量名”
    }

遍历数组:

//1.遍历数组

int[] arr = {1,3,242,43,5};
for (int a : arr) {//编译后:就是普通for循环,仅仅是写法上简单一些,没有提高效率
    System.out.println(a);
}

3).遍历集合:
	   ArrayList<String> list = new ArrayList<>();
    list.add("熊杰");
    list.add("李天阳");
    list.add("郭涛");
    list.add("陈卫广");

    for (String s : list) {//编译后:就是"迭代器"
        System.out.println(s);
        if (s.equals("陈卫广")) {
//                list.remove(s);//仍然会引发"并发修改异常"。而且不能拿到"迭代器"对象,因为使用的是"增强for",此时还没有"迭代器"对象。
            }
        }

注意:

增强for的特点:没有"循环变量",所以如果循环过程中需要使用"循环变量",那就不能用增强for循环了
只有当:从第一个元素遍历到最后一个元素时,才需要使用增强for,仅仅是写法简单而已。

泛型

泛型概述及作用

  1. 在我们之前定义集合对象时,使用了“泛型”:
    ArrayList list = new ArrayList<>();
  2. 泛型的作用:限制这个集合只能存储“某种类型”的引用,可以保证集合的安全。
    在创建对象时,可以不用“泛型”:
public class Demo05 {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();

        list.add("字符串");
        list.add(10);//Integer对象
        list.add(new Random());

        //可以存储任何类型,存储的时候很强大,但取出的时候就会有麻烦
        //如果取出时需要访问子类特有成员,就需要向下转型,就有风险
        for (Object o : list) {//取出时只能是Object类型接收
            //如果向下转型,就非常麻烦,而且有安全隐患
        }

        //所以,在使用集合时,通常我们只希望集合只存储一种元素
        //泛型:就可以限制这个集合只存储某种类型的引用
        ArrayList<String> strList = new ArrayList<>();
        strList.add("只能存字符串");

        ArrayList<Integer> intList = new ArrayList<>();
        intList.add(10);//只能存Integer对象
        for (Integer integer : intList) {//直接用Integer类型接收,安全的。
            
        }
    }
}

泛型的类

代码图解:

在这里插入图片描述
关于public class MyArrayList中的,这就是此类定义的“泛型”,只有这里定义了泛型,在创建对象时才可以指定“泛型类型”。
MyArrayList myArrayList = new MyArrayList<>();
的命名:
1).E:用什么字母都可以,可以大写、也可以小写;也可以是多个字母表示一个泛型名。
2).可以同时定义多个“泛型名”:<A,B,C>

泛型方法

在一个“方法”上也可以单独定义“泛型”

代码演示:
	public class Demo07 {
    public static void main(String[] args) {
        //1.调用fun()方法时,可以不指定泛型,这样泛型没有起到作用
        Demo07.fun("abc", 10, 3.14, true, '你');

        //2.调用fun()方法时,使用泛型
        Demo07.<String>fun("abc", "10", "3.14", "true", "你");
        Demo07.<Integer>fun(10, 20, 30, 40, 50);

    }

    //定义一个方法,要求可以接收5参数,这5个参数可以是任何的引用类型,但5个参数必须是相同的类型
    public static <T> void fun(T a1, T a2, T a3, T a4, T a5) {

    }
}

泛型接口

在定义接口时,也可以指定“泛型”,语法跟“类”一样

代码演示:
//定义一个有"泛型"的接口
interface Animal<E>{
    public void eat(E e);
}

//当子类实现有泛型的接口,或者继承有泛型的父类时
//1.子类可以:丢弃泛型【必须记住】
class Cat1 implements Animal{
    @Override
    public void eat(Object o) {
    }
}
//2.子类可以:指定为某种固定类型【必须记住】
class Cat2 implements Animal<String>{
    @Override
    public void eat(String s) {

    }
}
//3.子类可以:继承泛型,继续使用泛型【必须记住】
class Cat3<E> implements Animal<E>{
    @Override
    public void eat(E e) {
    }
}

public class Demo08 {
    public static void main(String[] args) {
        //1.创建Cat1对象,不能指定类型
//        Cat1<String> cat1 = new Cat1();//编译错误

        //2.创建Cat2对象,也不能指定类型
//        Cat2<String> cat2 = new Cat2();//编译错误

        //3.创建Cat3对象,可以指定类型
        Cat3<String> cat3 = new Cat3<>();//OK的
    }
}

泛型通配符

假如有以下几个类定义:
class Person{}
class Student extends Person{}
class Teacher extends Person{}
class JavaStudent extends Student{}
1).<? extends E>:表示可以是:E及其E的任何子类类型。
2).<? super E>:表示可以是:E及其E的任何父类类型。
3).<?>:表示:可以接收任何类型。

代码演示:

	public class Demo09 {
    public static void main(String[] args) {
        ArrayList<Person> list1 = new ArrayList<>();
        ArrayList<Student> list2 = new ArrayList<>();
        ArrayList<Teacher> list3 = new ArrayList<>();
        ArrayList<JavaStudent> list4 = new ArrayList<>();

        ArrayList<String> list5 = new ArrayList<>();


        fun1(list1);//OK的
        fun1(list2);//OK的
        fun1(list3);//OK的
        fun1(list4);//OK的
//        fun1(list5);//不可以

        fun2(list1);//OK的
        fun2(list2);//OK的
//        fun2(list3);//不可以
//        fun2(list4);//不可以
//        fun2(list5);//不可以

        fun3(list1);//OK的
        fun3(list2);//OK的
        fun3(list3);//OK的
        fun3(list4);//OK的
        fun3(list5);//OK的
    }

    //1.要求定义一个方法,可以接收ArrayList集合,
    // 集合里面可以是:Person及其他的任何子类类型,其他类型不可以
    public static void fun1(ArrayList<? extends Person> list){//设置泛型的:上限

    }

    //2.要求定义一个方法,可以接收ArrayList集合,
    //集合里面可以是:Student及其父类类型,其他类型不可以
    public static void fun2(ArrayList<? super Student> list) {//设置泛型的:下限

    }
    //3.要求定义一个方法,可以接收ArrayList集合,
    //集合里面可以是:任何引用类型。
    public static void fun3(ArrayList<?> list) {

    }
}

本文地址:https://blog.csdn.net/weixin_45144691/article/details/107343478

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网