集合



Collection
|--List:列表。
特点:
1,有序(存储元素的顺序和取出元素的顺序一致)
2,该集合中的元素都有索引,所以可以通过索引(角标)来访问元素。 
3,它可以存储重复元素。 

常见子类对象:记住:具体的子类对象,我们要学习应该是该对象的特有的数据结构,以及相关的特点。
|--Vector:jdk1.0就存在了。底层是数组结构的。可变长度数组,
原理:一旦原数组长度不够,会创建新数组,将原数组的元素复制到新数组中,并将新元素添加到新数组中。
Vector是同步的。
|--ArrayList:底层是数组结构,也是支持长度可变数组的。是不同步的。替代了Vector.因为效率高。 查询效率很高。 但是增删的效率很低。
|--LinkedList:底层是链接列表结构,简称链表结构。是不同步的。这个中结构的好处:对元素的增删非常效率很高。 查询的效率很低。

|--Set:集:中的方法和Collection一致,只要重点注意它的子类对象即可。取出元素只能使用迭代器。
特点:
1,不包含重复元素。(最大的特点)
2,这个集合存入元素的顺序和取出元素的顺序不一定一致。(具体的容器对象数据结构不同,顺序也有不同)
|--HashSet:底层数据结构是哈希表,不保证顺序,是不同步的。
哈希表:提供数组的查询效率而出现的。
将要存储的元素先通过哈希算法算出一个哈希值来标识存储的位置,代表着元素。
要找元素时,先将该元素通过哈希算法算出哈希值,在通过哈希值到哈希表中去查找。
特点:
1,不关系元素的顺序。
2,提高了查询效率。
3,不可能出现重复元素,因为哈希值都不同。即使相同,会再次判断两个元素的equals,内容是否相同。
如果内容也相同,不存,如果内容不同,存储。
所以哈希表要保证元素的唯一性,必须要依赖于两个方法。
1,hashCode
2,equals

|--TreeSet:可以给Set集合中的元素进行指定顺序的排序。非同步的。 
默认情况下,是通过元素的自然顺序排的序。
它保证元素唯一性的依据是看比较方法的返回结果是否是0.是0.就视为元素相同。不存。
TreeSet排序的方式一:让元素自身具备比较性,需要实现Comparable接口,覆盖compareTo方法。
这种比较方式成为自然顺序排序。

如果元素自身不具备比较性或者具备的比较性(自然顺序)不是所需要的。
这时只能用第二种方式 。
TreeSet排序的方式二:让容器自身具备比较性。容器一初始化就具备了比较功能。
因为容器时在对象构造时完成的。通过查阅,有一个构造方法TreeSet(Comparator).
在容器初始化时可以指定一个比较器。 
需要实现Comparator接口,覆盖compare方法即可。
所以这种方式成为比较器排序。 


集合的技巧掌握:
明确具体集合对象名称的后缀:
如果后缀是List,都所属于List体系。通常都是非同步的。
如果后缀是Set,都属于Set体系,通常也是非同步的。
这些体系中的其他子类对象,后缀不是所属接口名的,一般都是同步的。比如Vector.
这在常用子类对象中通用。 

明确数据结构:
对于jdk1.2版本的子类对象。
后缀名是所属的体系。
前缀名是就是数据结构的名称。
比如:
ArrayList: 看到Array,就要明确是数组结构。查询快。
LinkedList:看到Link,就要明确链表结构,就要想到 add get remove 和first last结合的方法.增删快。,

HashSet:看到hash,就要明确是哈希表。查询巨快,而且唯一性。
就要想到元素必须覆盖 hashCode方法和equals方法。 
TreeSet:看到Tree,就要明确是二叉树,可以对元素排序。
就要想到两种排序方式:
自然顺序:Comparable接口,覆盖compareTo(一个参数 )java.lang
比较器:Comparator接口,覆盖compare(两个参数);java.util
判断元素唯一性的依据就是比较方法的返回结果return 0;


----------------------------------------------------------------

泛型:jdk1.5版本,出现的技术。是一个安全机制。 


泛型技术的由来:
集合中可以存储任意类型对象,但是在取出时,如果要使用具体对象的特有方法时,需要进行向下转型,
如果存储的对象类型不一致,在转型过程中就会出现ClassCastException异常。
这样就给程序带来了不安全性。

在jdk1.5以后就有了解决方案。就是泛型技术。
解决方案就是,在存储元素时,就不允许存储不同类型的元素。
存储了就编译失败。 
所以就需要在存储元素时,在容器上明确具体的元素类型。这其实和数组定义很像。

好处:
1,将运行时期的ClassCastException异常转移到了编译事情,进行检查,并以编译失败来体现。 
这样有利于程序员尽早解决问题。 
2,避免了向下转型(强转)的麻烦


什么时候写泛型呢?
先简单理解:只要在使用类或者接口时,该类或者接口在api文当描述时都带着<>就需要在使用时,定义泛型。
其实,泛型无非就是通过<>定义了一个形式参数。专门用于接收具体的引用类型。
在使用时,一定要传递对应的实际参数类型。
集合中泛型的应用特别多见。

泛型的擦除:
泛型技术是用于编译时期的技术,编译器会按照<>中的指定类型对元素进行检查,
检查不匹配,就编译失败,匹配,就编译通过,通过后,生产的class文件中是没有泛型的。这就成为泛型的擦除。

泛型的补偿:
运行时,可以根据具体的元素对象获取其具体的类型。并用该类型对元素进行自动转换。




--------------------
泛型对对于程序的设计也有一定优化动作。

泛型类。
泛型方法。
泛型接口。

泛型的通配符。

泛型的限定。

-------------------
集合框架中的另一个顶层接口,Map。

Map:用于存储具备着对应关系的键和值。
而且要保证键的唯一性。
一次存储一对儿元素。

Collection一次存储一个元素,称之为单列集合。
Map集合一次存储一对儿元素,称之为双列集合。

Map常见方法:
1,添加。
v put(k,v):
void putAll(map);

2,删除。
void clear():清空集合。
v remove(key):通过键删除元素,并返回对应的值。

3,判断。
boolean containsKey(key);
boolean containsValue(value);
boolean isEmpty();

4,获取。
value get(key):根据键获取值。如果键不存在,返回null。可以用来判断一个集合中是否存在某一个键。

5,获取map中所有的元素(对应关系)。
Map是不具备迭代器的,获取原理就是将map集合先转成set集合。然后在使用迭代器。
Set<key> keySet();
Set<Map.Entry<key,value>> entrySet();
Colection<value> values();获取map集合中所有的值。 

----------------
Map体系:
|--Hashtable:底层是哈希表数据结构,是线程同步的,不允许null作为键,null作为值。
|--HashMap:底层是哈希表数据结构,是线程不同步的,允许null作为键,null作为值。替代了Hashtable。
|--TreeMap:可以对Map集合中的键进行指定顺序的排序,默认是使用键的自然顺序。当然也可以使用比较器。



什么时候使用map呢?

当分析问题时,发现其中存在着映射关系,这时应该想到两个容器,一个是map,一个是数组。
如果映射关系的一方是有序的编号(可以作为索引),而且映射关系的个数确定,建议使用数组。
否则,就使用map集合。 
凡是映射关系的出现,都可以使用查表法的思想去解决问题。 

其他集合什么时候使用呢?

如果要保证元素的唯一性,不存在映射关系,必须先考虑使用Set集合。
如果不需要保证唯一性,直接考虑List集合。



-----------------------------------------------------

























































  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值