1.为什么出现集合类?
2.因为我们经常使用大量的对象,根据对象的数量或操作(增,删,改,查)的不同
3.集合就是存储对象最常用的一种方式
4.我们使用不同的容器(数组已经不能满足需求),所以要学习不同的集合
* 集合类和数组的区别:
* 相同点:都是容器,都可以存储对象
* 不同点:数组中可以存储基本数据类型,长度是固定的,而集合只能存储对象
* 集合长度是可变的,集合可以存储不同类型的对象
* 体系的学习:看顶层用底层
* 集合按照数据结构的不同,分为不同类型的集合,所有集合的根是collection
* 集合的特点:
* 1.集合只用于存储对象,
* 2.集合长度是可变的,
* 3.集合可以存储不同类型的对象。
集合的体系:
不同功能的集合,经过不断的功能抽取,划分了不同的种类(List,Set)
所有集合的根是Collection
怎么学习集体?
先学习共有的功能,再学习特有的功能(看顶层,用底层)
Collection<E>
<>:Element集合中能放哪些元素
功能:
添加:
add(object obj)
addAll(Collection c):
删除:
clear()
remove(Object o)
removeAll(Collection<?> c)
判断:
contains(Object o)
containsAll(Collection<?> c)
equals(Object o)
isEmpty() :判断此集合有没有元素
个数:
size()
转数组:
toArray()
toArray(T[] a)
获取:
interator()
迭代:迭代是取出集合的一种方式
因为Collection中有iterator()
所以每一个子类集合对象都具有迭代器
=================================================
Collection
|-List 存储获取都是有序的,有索引的(特有),围绕索引展开的,允许有重复的元素,包含null元素
|-Vector 大小可变数组(数组结构),是线程安全的(1.0),是同步的
|-ArrayList 大小可变数组(数组结构),不是同步的,查询速度快,增删速度慢
|-LinkedList 链表结构,是不同步的,查询速度慢、增删速度快
Listiterator特有功能:添加功能,反向变量
|-Set 不包含重复元素 读取只能使用iterator,不保证有序,元素唯一
|-HashSet 哈希表结构(散列表结构),不保证有序,不是同步的
1.通过HashCode()计算哈希值,如果值不相同,就存储
2.如果哈希值相同,则通过equals判断对象是否相同,如不相同,则存储
|-LinkedHashSet:既保证不重又是有序(存取有序)的(链表和哈希表两种结构)
|-TreeSet 二叉数 有排序的特点
需要对象实现comparable接口重写compareTo() (自然排序或者默认排序)
需要对象实现comparator接口重写compare() (自定义排序)
查询多用:ArrayLIst
增删多用:LinkedList
List特有的方法:
添加:
add(int index, E element)
addAll(int index, Collection<? extends E> c)//添加集合就是添加集合中的所有元素
删除:
Object o = remove(int index)
修改:
Object o = set(int index, E element)//返回的是修改之前的元素
获取:
Object o = get(int index)
int i = indexOf(Object o)
int i = lastIndexOf(Object o)
List存储字符串去重:1
/*思路:
* 1.定义一个新集合用来存储不重复的元素
* 2.循环得到原来集合中所有的元素
* 3.判断新集合中是否包含原集合中的元素,如果不包含就添加到新集合中
* */
List存储字符串去重:2
/**
* 1.根据选择排序的思想,用第一个和后面所有比较,第二个和后面所有比较
* 2.如果相等就把后面的删除掉
* 注意:这种方法排序如果有两个相邻的相同元素会发生替代
* 就是如果把如果有相同的删除之后,后面的又是相同的,删除掉的那个角标就不再比了
* 去重就失败了,所以在删除之后 我们让返回那个角标又在比一次就行了
*/
List存储对象去重:
// 判断该元素是否在新集合中已经存在,如不存在,则存入新集合
/* 根据第1.步骤
* contains方法实际使用equals做比较集合中的元素
* 而当前元素是Person,当前equals是Object类中的方法,比较的是地址值。
* 而我们希望比较的是Person对象(重写equals,同姓名同年龄视为同一个人)。
* */
-----------------------------------------------------------------
LinkedList:
特点:
查询慢,增删块
创建对象:LinkedList li = new LinkedList();
添加(首尾),删除,修改,判断,获取
--------------------------------------------------------------
Set:
特点:
不保证有序。元素唯一、
创建对象:Set set = new HashSet();
功能:
添加,删除,(没有修改方法),判断,获取(只能使用迭代器)
HashSet
特点:哈希表(散列表)结构,查询很快
通过hashCode()计算存放的地址值,如果有元素计算除了相同哈希值,
通过equals()判断两个元素是否相同,如相同,只存一次
如不同通过链表形式存储(先计算,再判断)
创建对象:HashSet hs = new HashSet();
功能:
添加,删除,(没有修改方法),判断,获取(只能使用迭代器)
-------------------------------------------------------
TreeSet
特点:底层结构是自平衡的二叉树(元素可以排序)
如果集合创建时没有给比较器,那么元素必须实现comparable接口(默认排序)
给了比价器,那么会优先使用比较器,比较器实现了comparator接口(自定义排序)
创建对象:
TreeSet set = new TreeSet();
功能:
添加,删除,(没有修改方法),判断,获取(只能使用迭代器)
-------------------------------------------------------
set去重:
虽然是唯一的,但是当我们存储对象去重的话,就必须要重写equals的方法
hashCode()不影响equals()
只跟排序comparTo()有关
TreeSet和HashSet没关系
---------------------------------------------------
泛型:
概念:因为集合中能存储任意类型的对象,当我们使用从集合中取出的元素,一般需要转成元素本省特有的类型
这是通常需要强转,并且容易引发数据类型转换异常。为避免这个问题可以使用泛型。泛型就是解决编译
时期可能产生安全问题的一种安全机制
泛型的特点:1.提高了程序的安全性
2.将运行时期的问题转移到了编译期
3.省去了类型强转的麻烦传入
4.泛型类的出现优化了程序设计
使用:如果接口名或类名后面有<E/T/O>,就要使用泛型
泛型就是将数据类型作为实际参数传入<>,该数据类型只能是引用数据类型
泛型擦除:泛型只能使用在编译时期,编译结束生成的字节码时,字节码中并没有泛型,这种现象叫泛型擦除
泛型限定:对泛型的范围做了限制(最高限制和最低限制)
泛型类:泛型加在类名后
泛型方法:泛型加在方法上,方法上的泛型和泛型类上的泛型没有关系
泛型接口:泛型加在接口名后
泛型的上限:<? extends E>
泛型的下限:<? super E>
/**
* 高级for循环
* for(元素的数据类型 元素变量名:循环的目标){
* 循环体
* }
作用:简化了书写
用途:遍历集合和数组
局限性:只能遍历集合和数组必须有遍历的目标
*/
-----------------------------------------------------
Map:双列存储结构,集合是单列结构存储,集合存一个,Map存一对(键值对)
Map中的键是唯一的
功能:
添加:
v put(K key , V value) map的添加方法
void putAll(Map<? extends K,? extends V> m)
删除:
clear() 删除所有元素
v remove(Ovject Key) 根据key删除元素
判断:
boolean containKey(Object key) 判断是否包含指定的键
boolean containsValue(Object value) 判断是否包含指定的值
Boolean equals(Object o) 比较元素
isEmpty() 判断是否为空
获取:
v get(Object Key) 根据键获取值,存在就返回值,不存在就返回null
set<K> keySet() 获取所有的键
set<Map.Entry<K,V>> entrySet() 获取所有键值的映射(键值对对象)
Collection<V> values() 获取所有的值3
.。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
-------------------------------------------------
Map
|-Hashtable 哈希表结构,无序,键唯一,非null,同步
|-HashMap 哈希表结构,不保证顺序,键唯一,允许null,不同步
|-TreeMap 二叉数结构,排序,不同步的
-------------------------------------------------
Collection:提供了操作集合或返回集合的方法
reverse(List<?> list) 集合元素反转
reverseOrder() 反转自然排序顺序
reverseOrder(Comparator<T> cmp) 反转自定义比较器排序顺序
Arrays:操作数组的方法
|-asList把数组转成了集合
常用方法:
sort()
asList();
数组为什么转集合:数组转集合就是为了使用更多的方法。
注意:数组转成集合后,实际还是数组,不支持增删
/**
* 1.数组转成集合时,如果数组元素是引用数据类型
* 则该数组中的元素作为元素存入集合
* 2.数组转成集合时,如果数组元素是基本数据类型
* 则该数组对象作为元素存入集合
*
* 原因:asList是泛型方法泛型只能是引用数据类型
*/
/**
* 当一个类没有构造方法,也没有子类时,且类中都是
* 非静态方法,该类必然有一个静态方法能返回本类对象
* 该类采用了单列设计模式
*
*/
Collection.toArray();集合转数组
注意:集合转数组,就是为了限制方法的使用,入增删