集合 Set是不包含重复元素的集合接口,其子类均无法存放相同元素。最常用的子类是无序不可重复的HashSet。 HashSet集合由于是无序的,其判断唯一的依据是元素类型的hashCode与equals方法的返回结果。规则如下: 先判断新元素与集合内已经有的旧元素的HashCode值 如果不同,判断元素不同。 如果相同,再判断equals比较结果,返回true则相同,返回false则仍然不同。 所以,如果施工HashSet存储自定义类型,需要重写该类的hashcode与equals方法。(这里采取Eclipse自动生成,在知识点补充处详细介绍) 由于没有索引,所以HashSet集合按照传统索引的方式无法遍历,所以这里使用增强for循环。 增强for循环用于遍历容器,如数组与任意单列集合。 使用格式: for (集合内元素类型 临时变量 : 被遍历容器) { //使用临时变量依次操作容器中的数据 集合分类 单列集合Collection List:元素有序、包含重复元素、可使用索引 ArrayList:底层数据结构是数组结构,增删慢,改查快。 LinkedList:底层是链表数据结构,增删快,删除慢。 Vector:底层数据结构是数组结构,已被ArrayList替代。 Set:不包含重复元素 HashSet:通过Hash表结构判断元素唯一性。双列集合Map:键值映射关系 HashMap:对键进行Hash表约束的双列集合 集合与数组辨析 l 容器长度 集合长度可变 数组长度固定l 存储内容类型 集合存储引用数据类型 数组存储任意类型l 是否可存储不同类型数据 集合可以存储不同类型数据 数组只能存储相同数据类型 集合迭代(集合遍历) a) 迭代简介 类似ArrayList这样,使用索引进行集合遍历并不是常用的方法。数组与所有的单列集合均可以使用增强for循环完成数据遍历。 增强for循环又叫foreach循环,用于遍历容器,如数组与任意单列集合。 使用格式: for (集合内元素类型 临时变量 : 被遍历容器) { //使用临时变量依次操作容器中的数据 } b) 迭代器Iterator 增强for循环在底层使用的是迭代器Iterator来完成的。我们也可以直接使用迭代器Iterator来完成单列结合的遍历。 使用迭代器完成集合遍历的过程是反复获得集合中元素的过程,通常我们将这个反复获取的过程叫做迭代。 Iterator:迭代器 迭代器的使用步骤: 调用集合的iterator方法,获取迭代器对象 调用迭代器的hasNext方法判断是否有下一个元素 调用迭代器的next获取是否有下一个元素 c) 并发修改异常 迭代的常规用法中我们要尽量避免在迭代过程中为集合添加数据。否则会报错,原因是Java抛出了并发修改异常。 即在使用Iterator和增强for循环时,均避免类似操作。 泛型 我们在集合中大量使用到了泛型,这里来完整地介绍泛型知识。 a) 泛型概述 用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数传递。泛型替代了Object来代表任意类型,在编译时会擦除。 泛型是数据类型的一部分,我们将类名与泛型合并一起看做数据类型。 泛型的定义:定义泛型类可以预支地使用未知的类型。 泛型的使用:一般在创建对象时,将未知的类型确定具体的类型。 b) 泛型代码实现 l 泛型的定义与使用 泛型类: 定义:类名后<变量> 如:class A<E> {使用E完全类的定义} 使用:创建对象时确定类型 泛型方法: 定义:方法返回值前<变量> 如:public <T> void method(){使用T} 使用:调用方法时确定类型 泛型接口: 定义:接口后<变量> 如: interface B<T>{使用T完成接口定义} 使用: 1、定义类时确定类型 2、始终不确定类型,直到创建对象时确定类型 泛型通配符 定义:(查看ArrayList的构造方法)无法再类中使用 使用:调用方法时可以给予任意类型。 c) 泛型优点 提高程序的安全性 将运行期问题转移到了编译期 省去了类型强转的麻烦 优化了程序设计 |