黑马程序员->集合类 (1
来源:互联网 发布:linux查看内核版本 编辑:程序博客网 时间:2024/06/08 03:19
--------------------android培训、java培训、期待与您交流! --------------------
2......................集合类..............Collection..Collection...Collection
//为什么出现集合类?
面向对象对事物的体现都是以对象的形式,所以为了方便对
多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。
//数组和集合类同是容器,有何不同?
数组虽然也可以存储对象,但长度是固定的。集合长度是可变的。
数组中可以存储基本数据类型,集合只能存储对象。
//集合类的特点
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
Iterator Collection <-------------------------------Map
| / \ Produces / \
ListIterator List Set HashMap TreeMap
/ | \ | \--------| |
ArrayList | Vector HashSet TreeSet LinkedHashMap
LinkedList |
LinkedHashSet
Comparable<-->Comparator
//为什么会出现这么多的容器呢?
因为每一个容器对数据的存储方式都不同,这个存储方式称之为:数据结构。
2.1......ArrayList
创建一个集合容器,使用Collection 接口的子类。 ArrayList
1.添加元素 .add();
2.获取个数,集合长度。.size();
3.判断元素 .contains(x)/*是否存在x*/ .isEmpty(); //是否为空
4.删除元素 .remove(x)/*删除x*/ .clear()//清空集合
1.retainAll(2);//取交集,1中只保留和2中相同的元素。
1.removeAll(2);//去掉1中和2中相同的元素。
2.1.1...迭代器 Iterator
迭代器就是集合取出元素的方式。 Iterator
Iterator it = al.iterator();//获取迭代器,用于取出集合中的元素。
while(it.hasNext()){// .hasNext();返回类型是boolean,所以用while循环,依次取
sop(it.next());//出元素,直到取完,返回false,循环结束。
}
for(Iterator it = al.iterator(); it.hasNext(); ){
sop(it.next());//一般用for循环来写,循环完it对象就清空,节省空间。
}
/* 取出方式定义在集合的内部,这样取出方式就可以直接访问集合内中的元素。
取出方式就被定义成了内部类,而每一个容器的数据结构不同,所以取出的动作细节也不一样,
但是都有共性内容:判断和取出。 那么就可以将共性抽取。
那么这些内部类都符合一个规则。该规则就是Iterator,如何获取集合的取出对象呢?通过一个
对外提供的方法:iterator(); */
2.1.2.....List 集合
Collection
|----List ://元素是有序的,元素可以重复。因为集合体系有索引。
线程不同步 |--ArrayList: 底层使用的是数组数据结构。特点:查询速度快,但是增删稍慢。
|--LinkedList:底层使用的是链表数据结构。特点:增删速度很快,查询稍慢。
线程是同步的 |--Vector:底层是数组数据结构。jdk 1.0 的老方法,过时了。
|----Set ://元素是无序的,元素不可以重复。
List :特有方法。凡是可以操作角标的方法都是该体系特有的方法
增:.add(index,element); addAll(index,Collection);//可以再指定位置加入元素。
删:.remove(index); //可以删除指定位置的元素。
改:.set(index,element);//修改指定位置的元素。
查:.get(index); subList(from,to); ListIterator();//get可以通过角标获取元素。
ListIterator :
List 集合特有的迭代器, ListIterator 是 Iterator 的子接口。
在迭代时,不可以通过集合对象的方法操作集合中的元素。
因为会发生 ConcurrentModificationException 异常。
/* 所以,在迭代时,只能用迭代器的方式修改元素,可是 Iterator 方法是有限的,
只能对元素进行 判断,取出,删除 的操作。
如果想要其他的操作如 添加,修改等,就需要使用其子类接口: ListIterator 。
该接口只能通过 List 集合的 ListIterator 方法获取。*/
.hasPrevious();//向上索引。
Vector :
枚举就是 Vector 特有的取出方式,发现枚举和迭代器很像。其实枚举和迭代是一样的。
因为枚举的名称和方法都过长,所以被迭起取代了。
枚举和 Vector 是 JDK 1.0 版本的,被 迭代和 ArrayList 是 JDK 1.2 版本 取代了。
LinkedList :
链接列表数据结构。 特有方法:
addFirst(); addLast();
getFirst(); getLast();//获取但不删除,如集合中没元素,则出NoSuchElementException 异常。
removeFirst(); removeLast();//获取并且删除元素,如集合中没元素,则出NoSuchElementException 异常。
// 由于没元素时抛异常,在 JDK 1.6 版本中出现了替代方法:
offerFirst(); offerLast();
peekFirst(); peekLast();//获取但不删除,如集合中没元素,则返回 null;
pollFirst(); pollLast();//获取并删除,如集合中没有元素,则返回null;
如果list集合中,如 ArrayList ,要传入的集合是 new 出来的对象,如 Person 对象,而 Person 对象又有自己的
name 和 age 属性。需求是把属性相同的 Person 对象视为同一对象,不予存入。
那么,如果让集合自己去比较每个对象的话,是不能去除相同对象的,因为每个对象都是新 new 出来的,而集合默认比较
的是地址值,所以每个对象都不一样。所以,就必须覆盖 默认的 equals 方法,重写 equals 方法成 比较每个对象
的属性是否相同,这样才可以去除重复对象。
//集合内 remove(去掉某个元素) 方法,默认比较对象时,也是调用 equals 方法,如果不复写equals方法,就会
//默认认为对象都不相同,而无法 remove某个元素。
2.2....Set 集合....//元素是无序的(存入和取出不一定一致),元素不可以重复。
|---HashSet :底层数据结构是哈希表。线程是非同步的。
|---TreeSet :
Set 集合的功能和 Collection 是一致的。
HashSet 是如何保证元素唯一性的呢?
是通过元素的两个方法,hashCode和equals 来完成。
如果元素的HashCode值相同,才会判断 equals是否为true。
如果元素的hashCode值不同,不会调用equals。
//对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。
因为 HashSet 默认是先比较两个对象的 hashCode ,相同的话在去比较 euqals 。而每个对象的 hashCode 肯定
不会相同(因为都是新 new 出来的),就一定要在对象内复写 hashCode 方法,可以写成每个对象内名字
的 hashCode 方法(因为 String 对象已经复写了 Object 的 hashCode 方法,所以每个字符串的hashCode
都不相同)和加上对象年龄乘以某正数(为避免有对象算出来的 hashCode 值偶然相同了)并 return 返回
结果。然后还要复写掉 equals 方法(同 ArrayList 中复写基本相同)。
|----TreeSet :可以对Set集合中的元素进行排序。 底层数据结构是二叉树。
保证元素唯一性的依据: compareTo 方法 return 0 ;
TreeSet 排序的第一种方式:让元素自身具备比较性。元素需要实现 Comparable 接口,覆盖
compareTo方法。这种方式也成为元素的自然顺序,或者叫做默认顺序。
实现 Comparable 接口时,一定要复写抽象 compareTo 方法,在复写时,先判断一下传入的类是
否为要比较的类对象,如果不是要抛出 RuntimeException 异常,因为是复写父类方法,所以不能声
明异常,然后要把传入的 Object 对象强转回要比较的对象。然后用 if 语句判断。 return 数值。
/* TreeSet支持两种排序方法:1.自然排序。2.定制排序。 默认情况下,TreeSet 采用自然排序。
自然排序会调用元素的 compareTo 方法来比较元素之间的大小关系,然后将集合元素按升序
排序,这就是自然排序。
定制排序,自然排序是根据元素的大小,TreeSet 将它们以升序排序。如果要实现定制排序,如
实现降序排序,就要重 new 对象并实现 Comparator(比较器),复写其中 compare 方法,对象
上要关联该比较器。*/可用匿名内部类的形式来定制排序。
//排序时,当主要条件相同时,要判断一下次要元素。
2.2.2..二叉树 A元素
/ \
B(比A小) C(比A大)
/ \ / \
D(比B小) E(比B大) F(比C小) G(比C大)
// 最小的 最大的
TreeSet 的第二种排序方式。
当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身
具备比较性。
// 在集合初始化时,就有了比较方式。
当两种排序都存在时,以比较器为主。 -------|
定义一个类,实现 Comparator 接口,覆盖 compare 方法。
实现 Comparator 接口时,要复写 compare 方法,先将传入对象强转回该对象,定义为两个对象
的某个属性比较,调用属性的 compareTo 方法比较,并返回 return 数值。
2.3..泛型<>.............................................................................
2.3.1.....集合内如存入不同的类型对象,则会出 ClassCastException 异常
//类型转换异常,因为类型不同。
所以:
JDK 1.5 以后,出现新特性,用于解决安全问题,是一个安全机制。就是 <泛型>
好处:
1. 将运行时期出现的问题 ClassCastException ,转移到了编译时期。方便与程序员解决
问题,让运行事情问题减少,安全。
2. 避免了强制转换麻烦。
泛型格式;
// 通过 < > 来定义要操作的引用数据类型。
通常在集合框架中很常见,只要见到 < > 就是用来接收类型的。
当使用集合时,将集合中要存储的数据类型作为参数传递到 <> 中即可。
// 什么时候定义泛型类??
当类中要操作的引用数据类型不确定的时候,早期定义 Object 来完成扩展。
现在定义泛型来完成扩展。
//自定义泛型
泛型类定义的类型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体
类型后,所有要操作的类型就已经固定了。
为了让不同的方法可以操作不同的类型,而且类型还不确定,那么可以将泛型定义在方法上。
// 泛型定义在函数上,写在 返回值 的前面。
//静态泛型定义
静态方法不可以访问类上定义的泛型。如果静态方法操作的应用数据类型不确定,可以将
泛型定义在方法上。 //否者要出---无法访问上下文异常。
//泛型定义在接口上
...。泛型限定
泛型可以设定 < > 内要传入的对象指定为某个类型。
< ? > ? :通配符,也可以理解为占位符。
<? extends E > ://可以接受 E 类型或者 E 的子类型。---> 上限
<? super E > : 可以接受 E 类型或者 E 的父类型。---> 下限
--------------------android培训、java培训、期待与您交流! --------------------
- 黑马程序员---集合类1
- 黑马程序员->集合类 (1
- 黑马程序员:集合类
- 黑马程序员 集合类
- 黑马程序员-集合类
- 黑马程序员-集合类
- 黑马程序员 集合类
- 黑马程序员--集合类
- 黑马程序员----集合类
- 黑马程序员----集合类
- 黑马程序员--集合类
- 黑马程序员---集合类
- 黑马程序员---集合类
- 黑马程序员 集合类
- 黑马程序员-----集合类
- 黑马程序员:集合类——1
- 黑马程序员--集合类总结1
- 黑马程序员——集合类(1)
- UML实践----用例图、顺序图、状态图、类图、包图、协作图
- spring 之 springMVC 学习1
- 黑马程序员->常用API (1
- flash跨域策略文件crossdomain.xml配置详解
- poj 1733 Parity game
- 黑马程序员->集合类 (1
- struts2+spring+hibernate整合时所需的jar包
- 基础知识
- struts---No result defined for action org.crazyit.app.action.LoginAction and result error
- [全程建模]UML被肆意乱用,怎么可能解决问题
- 黑马程序员->集合类 (2 Map
- NorFlash与NandFlash对比
- SpringMVC—介绍
- 报表中如何去掉字符串中的首字符或末字符