黑马程序员_集合笔记2

------- android培训java培训、期待与您交流! ----------

1.集合

作用: 专业的存储对象的容器

集合也理解一类特殊的对象,这个对象称之为为容器,存储其他对象. 

注意: 集合存储的仅仅是对象的引用,非对象本身. 

2.集合体系

|---Iterable

public Iterator iterator();  该方法定义集合获取迭代器对象的规范. 

jdk5.0 出现. 为了支持增强for 新特性... 

|---Collection(接口) 

... 

|---List(子接口)

特点: 元素在集合中角标.元素有序,元素可重复的. 

|---ArrayList(实现类)

原理: 数组实现,内存地址连续,查找快,增删慢.

|---LinkedList

原理: 双向链表,内部地址不连续,查找慢(中间节点),增删快

|---Vector 

jdk1.0出现, 方法名长, 线程同步(单线程性能低),底层数值实现扩容是100% 浪费内存的. 

在jdk1.2 出现了集合体系,体系出出现ArrayList 替代该类.  

|---Set(子接口)

特点: 无序(集合存储元素时,按照内部的规则,存储和排序),元素不可重复. 

|---HashSet

hashCode equals 

原理: 哈希表实现(hashtable) 就是一个数组.

 该集合是如何保证元素的唯一性?, 通过元素的两个方法hashCode 和equals.

 集合在存储每一个元素时,就会调用元素的hashCode方法,计算出该元素的哈希值,和集合已经存储的元素的哈希值比较,

如果不重复 ,集合就直接存储元素, 如果重复集合调用元素的equals 比较, 当equals 方法为true,集合是元素为重复的. 无法添加

|---LinkedHashSet

该集合是HashSet 的子类. 普通的HashSet 是无序的, 会打乱元素存储的顺序. 该集合会通过双向链表保存元素插入的位置. 

|---TreeSet

原理: 二叉树实现. 不但可以保证元素的唯一性,还可以给元素排序. 

排序方式一: Comparable

让集合中存储的元素具备比较性. 元素(对象)所属的类实现Comparable 接口, 重写compareTo 方法. 在方法内部,制定比较规则,返回正整数,负整数和0. 

排序方式二:  Comparator 

给集合指定比较器对象. 自定义类实现Comparator 接口, 重写compare 方法, 在方法内部,进行比较,制定比较规则. 

|---Iterator(接口)

定义类迭代器的规范. 

public boolean hasNext();

public Object next(); 

public void remove();  

该接口规范了迭代器具备的基本的行为(功能)

在每一个集合实现类的内部,都存在一个私有成员内部类实现了该接口. 重写了方法. 保证类每一个集合类内部都存在一个迭代器类. 

并且每一个集合实现类都具备一个公有的方法获取这个私有的迭代器内部类对象 public Iterator iterator(); 

注意: 

Iterator 和Iterable 区别:

Iterable 接口:

jdk5.0出现的. 是集合体系的顶层接口. 

只有一个方法, 规范了获取迭代器的基本行为. 

Iterator 接口:

jdk1.2 出现.  在集合实现类的内部实现类该接口. 

三个方法, 规范了迭代器的基本行为. 

任务: 

Collection 

?

List

?

Set 

集合. 

尽量多的方式遍历出集合中的所有元素. 

3.迭代器(Iterator)

取出集合中的元素. 

如何取出Collection 集合中的元素. 

toArray(); 只能通过该方法将集合为数组,再遍历数组,取出元素. -> 不专业(面向对象)

如何取出List 集合中的元素

List 集合有角标的,可以通过get(int index) 取出元素

如何取出Set 集合中的元素. 

该集合没有角标,没有get 方法, 只能通过toArray()方法将集合为数组,再遍历数组,取出元素.

在集合体系中缺乏一个统一的取出集合元素的方式...  虽然List 有get 方法,但是不能为集合通用的... 

java集合体系,专业的设计了一个对象, 该对象专业的用于取出集合的元素, 该对象比较特殊,存在于集合的内部... 

将该对象称之为迭代器对象. 

接口:

Iterator  -> 如何成为迭代器... 

public boolean hasNext(); 

检测是否还有元素. 

public Object next();

取出一个元素.  

public void remove();

删除一个元素. 

该接口,定义了迭代器的基本的规范. 只要是一个迭代器,就应该具备这些方法... 

由于每一个集合类,都应该有一个迭代器可用. 在每一个集合类的内部,都存在一个成员内部类实现类该接口. 保证每一个集合类的迭代器对象都可以使用这些方法. 

所谓的迭代器,存在于每一个集合类的内部,成员内部类. 

接口: 

Collection

... 

public Iterator iterator(); -> 获取一个迭代器

迭代器类,是一个私有的成员内部类存在于集合类的内部, 如何有效的获取迭代器对象(私有成员内部类对象), 提供公共的方法获取. 

由于每一个集合类,都应该有一个迭代器可用. 保证每一个集合类都应该具备一个公共的获取迭代器对象的方法... 如何保证? 将方法抽取到集合的顶层接口Collection中. 

注意: 集合类不是直接实现类Iterator 接口, 集合类不是迭代器, 而是在集合类的内部类存在一个私有的成员内部类, 该类才是一个迭代器... 

4.集合体系之Set集合

|---Collection

|---List

特点: 元素有序,有角标,元素可重复. 

|---Set(接口)

该体系的特点: 

该集合不包含重复元素, -> 元素是不可重复的. 

元素还是无序的. 

特点: 无序,元素不可重复. 

该Set接口中没有特有方法... 

|---HashSet(实现类)

底层是hashtable(哈希表)实现. 

通过元素的hashCode和equals 方法保证元素的唯一性的. 

|---LinkedHashSet(实现类) 

是HashSet 子类, 和HashSet 不同,之处,使用了链表保存了元素插入的顺序. 

|---TreeSet(实现类)

重点学习实现类,例如HashSet TreeSet 集合的, 具体的集合类是如何确保元素的唯一性的(如何保证元素的不可重复的)

5.集合之HashSet 

实现原理. 如何保证元素的唯一性的. 

通过元素的两个方法. hashCode 和eqauls 方法. 

集合HashSet存储每一个元素时,调用该元素的hashCode方法, 获取元素的哈希值. 

哈希值不同

如果该元素的哈希值和集合已经存在的元素的哈希值不相同,集合直接将元素视为非重复,将元素存在集合中.

哈希值相同

如果该元素的哈希值和集合中已经存在的元素的哈希值相同的话, 集合会调用这个元素的equals 方法进行比较(确认元素是否是一样的)

equals 为true

集合将新元素视为重复元素,重复元素无法添加, add 方法返回false .  

equals false 

当集合将新元素视为不同元素,该元素添加到集合中. 和哈希值一样的元素存在一个哈希桶中,这叫做哈希冲突. 

建议: 重写良好的hashCode 和equals 方法. 否则 hashSet 集合的性能会降低. 

特殊的哈希冲突: 性能最低的哈希表.  HashSet 存储了10000个元素, 这个写元素的哈希值都相同,但是equals 都为false ...  1w 个元素存储在一个哈希桶中,非常低下的哈希桶. 

建议:

hashCode 和equals 都有重写... 

重写hashCode 和equals 方法时, 如果两个对象的equals 结果为true, 那么这两个对象的hashCode 也应该一致(相等)

练习: 

设计Worker类,为Worker 类增加id 属性,用来唯一标识一个员工。即:如果员工的id 不同,则不管其姓名、年龄、工资是否相同,都认为是不同的员工。使用HashSet 结合存储多个员工对象,id 重复的不能存储. 

去除数组的重复元素.

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

{7,1,2,3,5,6}

6.集合之TreeSet 

该集合最大的特点,会给集合中的元素进行自然排序... 

并且保证元素的唯一性. 

TreeSet集合是如何给集合的元素排序,并保证元素的不可重复的?

底层使用,二叉树实现(红黑树)

较小的元素挂在数的左边,大的元素挂载树的右边.  左小右大. 一个节点最多只能2个字节... 

如果使用的是TreeSet 集合存储自定义元素的话,一定要保证自定义的元素可以进行大小的比较. 如何保证元素可以经大小的比较. 

元素所属的类,实现接口Comparable ,重写compareTo方法.  注意: compareTo 方法的返回值是int 值, 集合TreeSet 根据方法的返回值决定元素的位置. 

TreeSet 集合如何元素的唯一性, 如何实现元素的排序?

方式一: 元素自身具备比较性. 

例如: String类.就是这样的. 

Comparable -> compareTo 

集合TreeSet 在存储元素时(元素是就是一个对象)

元素(对象)所属的类实现Comparable 接口. 并重写compareTo 方法. 在方法内部建立元素的比较规则. 返回正整数,负整数,0. 

集合TreeSet 在存储第二个元素时,会将第二个元素和第一个元素使用compareTo 方法进行比较. 集合TreeSet 根据方法的返回值,判断第二个元素是大于小于还是等于第一个元素. 

方式二: 比较器. 

Comparator compare. 

方式一: 存在固定的缺陷. 

如果你只能使用一个类(仅仅获得了.class 文件),不能修改一个类(没有获取源码).刚好该类又没有实现Comparable接口. 不能再使用TreeSet集合存储该类对象...

或者该类默认具备的比较方式,不是程序中需要的. 都可以使用第二种方式解决. 

自定义类实现Comparator 接口.重写该接口中的compare 方法. 创建该实现类对象,作为TreeSet 对象的初始化参数传递给集合TreeSet. 

使用TreeSet 集合存储元素. 元素的类本身就实现了Comparable 接口. 同时又给集合TreeSet 指定了Comparator 接口的实现类对象.  集合会采用一种,采用的是Comparator 接口的实现类对象 制定的比较规则...

7.泛型:

ArrayList<泛型类型> list=new ArrayList<泛型类型>();

注意: 泛型类型不能是基本数据类型. 必须是类类型(引用类型)

集合声明了泛型之后,仍然可以存储基本数据类型的原因是jdk5.0 出现了自动装箱. 

泛型的好处: 

一. 解决运行时异常

集合声明和泛型类型之后,只能存储该类型的元素. 就不需要取出元素时,进行类类型转换, 就不会出现运行时异常(ClassCastException)

二. 取出元素不需要转型了. 

存储元素时,集合的泛型类型声明的是什么,取出元素的类型就是什么. 

8.Map集合. 

Collection

一次存储一个对象作为集合的一个元素... 

程序更复杂的需求. 

需要保存对象和对象之间的关系的. 如何保存? 

贪吃蛇游戏: 

配置信息: key  value 

              高           10

              宽  20

集合特殊,一次可以存储2个对象, 并保存这个对象之间一一对应的映射关系... 

key    value 

学号 <->学生

身份证号 <->人

查看文档:

该集合Map 和Collection 体系不同,一次存储2个对象.这两个对象在Map集合中称之为键(key)和值(value)

该集合key 不能重复(唯一的), 值和键之间的映射是一一对应的. 

Map 接口的方法:

put(K key, V value) 

一次添加两个对象键(左)和值(右),作为map 集合的一个元素.

putAll(Map m) 

remove(Object key) 

clear() 

get(Object key) 

isEmpty() 

size() 

containsKey(Object key) 

containsValue(Object value) 

put(K key,V value);

如果K 在集合中存在, 就是修改的效果. 旧值和键解除对应关系,键和新值建立关系. 并返回旧值... 

键是唯一的,不能修改的. 能修改的是,键对应的value值. 

其他:

values() 

取出所有的值. 返回的是一个Collection .存储了map 所有的值. 

keySet() 

取出所有的键. 

entrySet()

问题:

map 集合,取出集合中的所有的元素... 

9.Map集合之HashMap

1. Map 集合在于键是唯一的. 键不可重复的. 该集合是如何保证键的唯一性? 

如何验证两个键是同一个呢? 设计到比较了. 

该集合是通过键的的hashCode 和equals 方法来验证键的唯一性. 

如果使用Map集合存储自定义对象作为键, 自定义对象一定要重写hashCode 和equals 方法.否则使用是默认父类(Object)的hashCode equals 方法进行验证. 无法检测出重复的键.  

10.Map集合之TreeMap

1. Map 集合键是唯一的. 键不可重复, 该集合是如何保证键的唯一性? 

该集合不但可以保证键的唯一性,还可以该键排序. 

如何排序

方式一:

TreeMap 集合存储的键(对象)所属的类,实现Comparable 接口,重写compareTo方法,建立键的比较规则. 

集合TreeMap 在存储第二个键值对起调用键的compareTo方法 和第一个键进行比较,根据返回值决定键的位置... 

方式二:

如果键不具备比较规则. 可以直接给集合TreeMap 指定比较器对象. 

自定义类实现Comparator 接口,重写compare 方法. 通过TreeMap 的构造函数接收该对象. 

11.集合工具类Collections 

现在有一个ArrayList 集合, 该集合中存储了若干元素. 

不但能够给ArrayList 集合中的元素排序(元素的大小升序... ) ,还需要保留重复元素. 

图书管系统中就需要使用... 

 

猜你喜欢

转载自blog.csdn.net/u014231961/article/details/84700818