黑马程序员技术交流社区

标题: [石家庄校区]day02-Collection-泛型笔记 [打印本页]

作者: cccyj    时间: 2018-11-14 16:49
标题: [石家庄校区]day02-Collection-泛型笔记
本帖最后由 cccyj 于 2018-11-14 17:03 编辑

Collection单列集合2-1

        共性方法2-2

        迭代器2-3

        增强for2-4

泛型2-5


2-1

集合: 长度可变容器, 可以存储多个对象


集合和数组的区别:

        1. 数组长度不可变; 集合长度可变

        2. 数组可以存基本类型或引用类型, 只能存同一种类型; 集合只能存储引用类型元素, 可以是多种类型元素



2-2


java.util.Collection<E>接口:

        // 成员方法(子类都会实现)

        boolean add(E e): 把给定的对象添加到当前集合中

        void clear(): 清空集合中所有的元素

        boolean remove(E e): 把给定的对象在当前集合中删除

        boolean contains(E e): 判断当前集合中是否包含给定的对象

        boolean isEmpty(): 判断当前集合是否为空(没有元素)

        int size(): 返回集合中元素的个数

        Object[] toArray(): 把集合中的元素,存储到数组中


        Iterator<E> iterator(): 获取集合的迭代器对象


测试Collection接口的方式:

        使用多态方式创建对象: Collection c = new ArrayList();

        编译看左边, 这样只能调用Collection接口中定义的方法, 不会出现子类特有方法


2-3

迭代:

        类似于遍历, 判断是否有下一个元素, 有则取出下一个, 直到没有

迭代器:

        用于遍历集合的对象


java.util.Collection<E>接口:

        // 成员方法(子类都会实现)

        Iterator<E> iterator(): 获取集合的迭代器对象


java.util.Iterator<E>接口: 迭代器

        // 成员方法

        boolean hasNext(): 判断是否有下一个元素

        E next(): 获取下一个元素


        void remove(): 删除next指向的元素


使用迭代器遍历集合的3步:

        1. 使用集合对象的 iterator() 获取迭代器对象, 用 Iterator 接口接收.(多态)

        2. 使用 Iterator 接口中的 hasNext() 方法, 判断是否有下一个元素

        3. 使用 Iterator 接口中的 next() 方法, 获取下一个元素


使用迭代器遍历集合的标准写法:

Iterator<元素类型> iterator = 集合对象.iterator();

while (iterator.hasNext()) {

    元素类型 变量名 = iterator.next();

}

迭代器的实现原理

集合和迭代器对象的关系:

        每个集合都有对应的一个迭代器对象


迭代器的原理:

        迭代器有一个指针(其实就是个变量, 保存索引值), 最初指向集合的 0 位置

hasNext() 方法可以判断当前索引是否有元素

next() 方法返回当前元素, 并移动指针到下一个索引


迭代器的并发修改异常

并发修改异常的原因:

        在使用迭代器迭代的过程中, 如果执行了改变集合长度的操作 (如 add(), remove(), clear()), 则会抛出 ConcurrentModificationException 并发修改异常.


如何避免:

        1. 迭代过程中不要修改集合长度

        2. 在迭代的过程中添加, 删除元素, 要使用迭代器自带的方法, 而不能使用集合的方法

                Iterator中的 remove() 方法

                ListIterator中的 add(), remove() 方法


2-4

增强for:

        也称foreach循环, JDK 5出现, 用于遍历集合, 底层采用迭代器


作用:

        遍历数组

        遍历集合


增强for格式:


    for(元素的数据类型 变量名 : Collection集合或数组名){

        //操作代码  

    }


    // 数组示例

    int[] arr = {1,2,3};

    for (int i : arr) {

        System.out.println(i);

    }


        // 集合示例

    Collection<Integer> c = new ArrayList<>();

    for (int i : c) {

        System.out.println(i);

    }


增强for对于数组和集合的操作:

        对数组只是写法上的优化, 底层还是普通for循环

        对集合是通过迭代器实现的


2-5

泛型: Generic Type. JDK 5 增加. 是一种未知的数据类型

        定义集合时, 某些方法不知道使用什么类型时, 就可以使用泛型

        创建集合对象时, 需要确定泛型具体的类型


泛型可以看作是一个"变量", 用来接收数据类型

定义:

<E>: 声明了一个泛型 (声明了一个变量)

E: 使用E这种类型作为数据类型  (参数数据类型, 返回值类型)

使用:

ArrayList<Integer>: 确定了泛型的具体类型


泛型的好处:

        1. 避免了类型转换的麻烦

        2. 将运行时的类型转换异常, 转移到了编译时期 (有利于程序员提前发现问题)

定义泛型

<泛型名>


泛型的"定义"和"使用"

        泛型在"定义"时, "不能是"具体的类型, 只是一个变量名: public class ArrayList<E> {}

        泛型在"使用"时, "必须是"具体的数据类型 ArrayList<Integer>


    // 带有泛型的类定义格式

    修饰符 class 类名<代表泛型的名字> {  // 泛型的变量一般用一个大写字母表示, 但也可以是多个字母


    }


类中的泛型, "在创建对象时", 确定泛型的具体类型



定义含有泛型的方法与使用

方法中的泛型定义位置:

修饰符返回值类型之间


// 带有泛型的方法定义格式

修饰符<代表泛型的名字>返回值类型方法名(参数){


    }


方法中定义泛型后, 返回值类型和参数类型都可以使用泛型


方法泛型的使用:

"在调用方法时"确定泛型的具体类型



泛型定义总结:

        定义在类上的泛型:

                有效范围: 整个类中都有效

                何时确定具体类型: 创建该类对象时确定泛型的具体类型

        定义在方法上的泛型:

                有效范围: 方法中(包括返回值类型和参数类型)有效

                何时确定具体类型: 调用方法传参时确定泛型的具体类型

        定义在接口上的泛型:

                有效范围: 接口中

                何时确定具体类型:

                        1. 子接口或实现类定义时确定泛型的具体类型

                        2. 创建实现类对象时确定泛型的具体类型


泛型通配符

泛型通配符:

        不知道使用什么类型来接收时, 此时可以使用 <?> 来表示未知通配符

        示例: List<?> list  接收泛型是任意类型的List对象

        public void addAll(List<?> list){

                        // ...

        }


                ArrayList<Integer> list1 = new ArrayList<>();

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

                addAll(list1);

                addAll(list2);



        注意: 只能接收数据, 不能调用方法存储元素

                List<?> list 这种集合不能调用 add() 添加元素, 只能调用 get() 获取元素

                List<?> list 其实是一个变量, 所以可以将一个集合赋值给它

                        如: List<?> list = new ArrayList<String>();  // 正确

                但是不能直接new 泛型为?的集合对象:

                        如: List<?> list = new ArrayList<?>();  // 错误

        使用方式:

                不能创建对象使用

                只能作为方法参数使用. (减少方法重载)


泛型的上限:

        格式: 类型名称<? extends 类名> 对象名称

        示例: List<? extends Number> list

        作用: 只能接收泛型为该类型及其子类的对象 (Number及其子类的泛型)


泛型的下限:

        格式: 类型名称<? super 类名> 对象名称

        示例: List<? super Number> list

        作用: 只能接收泛型为该类型及其父类型的对象 (Number及其父类的泛型)







欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2