------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
学习日记:集合部分
为什么出现集合类?
面向对象对事物的体现都是以对象的形式,为了方便对多个对象的操作,就对对象进行存储。
集合就是存储对象最常用的一种方式.
数组和集合都是容器,两者有何不同?
**数组长度固定,而集合长度是可变的
**数组值可以存储对象,还可以存储基本数据类型;而集合只能存储对象
**数组存储数据类型是固定的,而集合存储的数据类型不固定
集合类的特点:
集合只能存储对象
集合的长度是可变的
集合可以存储不同类型的对象
数据结构:
栈:
特点: 先进后出
队列:
特点: 先进先出
数组:
特点: 增删慢, 查找快
链表:
特点: 增删快, 查找慢
Collection:
集合 VS 数组
数组:
存储的元素类型 必须要相同
长度固定
集合:
存储的元素类型 可以不一样
长度不固定,大小随便变化
Collection集合中的方法:
添加功能:
(掌握)boolean add(Object obj):在此集合的最后添加一个新的元素对象
boolean addAll(Collection c):在此集合的最后添加一个新的集合中的所有元素对象
删除功能:
(掌握)void clear():清空此集合
(掌握)boolean remove(Object o):在此集合中删除输入的元素对象,删除了就返回true。此集合中没有输入的元素对象 o 返回false
boolean removeAll(Collection c):在此集合中删除所有与输入的集合中相同的元素对象,删除了哪怕一个也返回true
判断功能:
(掌握)boolean contains(Object o):判断此集合中是否包含输入的元素对象,
boolean containsAll(Collection c):判断此集合中是否包含输入的集合中所有的元素对象
(掌握)boolean isEmpty() :判断此集合是否为空
长度功能:
(掌握)int size() :返回此集合的长度
转换功能:
(掌握)Object[] toArray() :返回此集合的Object数组
遍历功能:
(掌握)Iterator iterator() :返回一个 Collection迭代器
交集功能:
boolean retainAll(Collection c) :返回此集合与输入集合的交集的元素对象
Iterator中的方法:
boolean hasNext(): 判断集合中 ,是否还有需要遍历(迭代)的元素
Object next() : 获取元素
可能会发生 没有找到元素的错误 NoSuchElementException
List:
Collection
|- List
|- ArrayList
|- Vector
|- LinkedList
|- Set
|- HashSet
|- TreeSet
List集合 与 Set集合的区别??
List:
有序的集合(元素的存与取的顺序一致)
可以存储重复的元素
允许多个 null 元素
Set:
无序的集合(元素的存与取的顺序不同)
不能够包含重复的元素
允许一个 null 元素
List集合的特有方法:
添加功能:
(掌握)void add(int index, Object element):在指定的位置中添加指定的元素对象
boolean addAll(int index, Collection c)
:在指定的位置上添加指定的集合,
获取功能:
(掌握)Object get(int index):获取此集合中指定角标的元素对象
(掌握)int indexOf(Object o):获取此集合中指定元素对象的角标,没有返回-1
int lastIndexOf(Object o):获取此集合中指定元素对象最后一次出现的位置
Lis subList(int fromIndex, int toIndex):获取此集合的子元素对象集合,包含头不包含尾
删除功能:
(掌握)Object remove(int index):删除此集合中指定位置的元素,并返回该元素,
修改功能:
(掌握)Object set(int index, Object element):修改此集合中指定位置的元素并返回该元素,
遍历功能:
(了解)ListIterator listIterator():获取list集合的特有迭代器,该迭代器有增删改查的功能,可以再迭代过程中进行
注意:
ConcurrentModificationException 并发修改异常
出现问题的原因在于, 迭代集合的过程中, 集合内的元素发生了改变,导致该异常的发生
List集合下的子集合的特点:
ArrayList:
底层: 数组结构
线程不同步,说白了, 就是不安全,使用起来有安全隐患,但是执行效率高
jdk1.2
当往ArrayList里面存入元素没什么要求时,即只要求有序就行时;
LinkedList:
底层: 链表结构
线程不同步,说白了, 就是不安全,使用起来有安全隐患,但是执行效率高
jdk1.2
Vector:
底层:数组结构
线程同步, 说白了, 就是安全, 使用起来没有安全隐患, 但是执行效率低
jdk1.0
Stack:
底层: 栈结构
Stack 是 Vector的子类
特点: 后进先出(LIFO)
一般情况下:
如果要求增删快,考虑使用LinkedList
如果要求查询快,考虑使用ArrayList
如果要求线程安全,考虑使用Vector。
ArrayList:
LinkedList:
特有方法:
public void addFirst(Object e):在集合的顶端添加元素
public void addLast(Object e):在集合的末端添加元素
public Object getFirst():在集合的顶端取出元素,但不影响集合
public Object getLast():在集合的末端取出元素,但不影响集合
public Object removeFirst():在集合的顶端删除元素,返回删除的元素
public Object removeLast(): 在集合的末端删除元素,返回删除的元素
Vector:
特有方法:
public void addElement(E obj) ----- add(Object obj):在集合的末端添加元素
public boolean removeElement(Object obj) --- remove(Object obj):删除集合中指定的元素,删除了返回true,没删除返回false
public void removeElementAt(int index) --- remove(int index):删除指定角标的元素,角标超出会报错:角标越界
public void setElementAt(E obj, int index) -- set(int index, Object obj):将指定位置的元素替换为指定的元素
public Enumeration
elements() ---- iterator():Vector集合特有的迭代器,枚举
Enumeration -- Iterator
boolean hasMoreElements() ---- hasNext():判断迭代器中是否还有下个元素
E nextElement() ---- next():取出迭代器中的下个元素
Stack:
特有方法:
public boolean empty() 测试堆栈是否为空。
public E peek() 查看堆栈顶部的对象,但不从堆栈中移除它
public E pop() 移除堆栈顶部的对象,并作为此函数的值返回该对象
public E push(E item) 把项压入堆栈顶部
public int search(Object o) 返回对象在堆栈中的位置,以 1 为基数
增强for循环:
jdk5新功能,用来替换iterator 迭代器
格式:
for ( 数据类型 变量名:数组名或者集合名) {
//变量名 代表数组或集合中的每一个元素
}
泛型: Genericity
为什么会出现泛型?
因为集合存放的数据类型不固定,故往集合里面存放元素时,存在安全隐患,
如果在定义集合时,可以想定义数组一样指定数据类型,那么就可以解决该类安全问题。
JDK1.5后出现了泛型,用于解决集合框架的安全问题。
泛型是一个类型安全机制。
概述: 它是在编译期,进行数据的类型约束
哪里可以使用泛型:
类
接口
方法
泛型的定义 : <数据类型>
泛型类: 就是在类上 定义泛型
好处:可以让方法中的参数,在创建对象的时候来确定, 使用的更加灵活
如: class Person {
public void show(T t) {
SOP(t);
}
}
泛型方法: 就是在方法上 定义泛型
好处:可以在使用方法的时候,来确定参数的类型, 实现每次调用接受不同类型的数据
如:
class Test {
//普通泛型方法
public QQ show( QQ q ){
SOP( q );
return q;
}
//静态泛型方法
public static Niu method( Niu n ){
SOP( n );
return n;
}
}
泛型接口: 就是在接口上 定义泛型
好处:灵活,可以在实现接口的时候来明确泛型的类型, 或者在创建对象的时候,来明确泛型的类型
如:
interface Inter {
public abstract void show(TT t);
}
//方式1 实现接口的时候来明确泛型的类型
class Test1 implements Inter {
public void show(String t){
SOP( t );
}
}
//方式2 创建对象的时候,来明确泛型的类型
class Test2 implements Inter {
public void show(QQ q){
SOP(q);
}
}
new Test2; //这个时候 确定的泛型的数据类型
泛型中的通配符: 可以匹配任意数据类型
格式: >
如:
ArrayList = new ArrayList();
ArrayList = new ArrayList();
ArrayList = new ArrayList();
public void print( ArrayList> objs){
for (Object obj : objs) {
SOP( obj );
}
}
泛型的边界(上边界、下边界):
ArrayList = new ArrayList();
ArrayList = new ArrayList();
ArrayList = new ArrayList();
// ? extends Person 定义 上边界
public void print( ArrayList extends Person> persons){
...
}
//? super Boy 定义 下边界
public void print2( ArrayList super Boy> persons ){
...
}
上边界: ? extends Person
?代表着Person本身, 或者Person的子类
下边界: ? super Boy
?代表着Boy本身, 或者Boy的父类
使用泛型时候的注意事项:
1: 定义泛型数据类型的时候, 要求左右两端的泛型的数据类型要一致
ArrayList list = new ArrayList(); 正确
ArrayList list = new ArrayList(); 错误
2: jdk7的新特点 菱形泛型 , 简化形式
ArrayList list2 = new ArrayList<>();
3: 泛型的约束,它是编译器的数据类型约束, 当编译后生成的class文件中,没有泛型的约束
Set集合:
特点:
不能够存储重复元素
无序的集合(元素的存与取顺序不同)
线程不同步的集合,有安全隐患
Set集合的继承关系:
HashSet集合:
底层: 哈希表结构
无序
LinkedHashSet集合:
底层: 哈希表结构 + 链表结构
有序
它是HashSet集合的子类
TreeSet集合:
底层: 二叉树结构
无序的集合(元素的存与取顺序不同)
有序(元素按照自然排序接口 或者 比较器接口来排序)
HashSet:
如何保证元素的唯一性?
重写hashCode()方法 与 equals() 方法
HashSet集合对象 底层是通过 HashMap集合来创建的
TreeSet:
如何保证元素的唯一性与排序的?
方式1: 通过实现自然排序接口 Comparable [ compareTo(Object obj ) ]
方式2: 通过实现比较器接口 Comparator [ compare( Object o1, Object o2 ) ]
返回值:
等于0 : 代表 两个对象相同, 新元素不存储到集合
大于0:
小于0:
代表 两个对象不同, 新元素存储到集合, 同时排序
可以按照指定的规则进行排序
注意: API中提供的类, 通常都实现了 Comparable接口,而我们自己创建的类没有实现,所以,自己的类 需要实现接口
基本数据类型或字符串对象均实现了Comparable接口,故同种类型基本数据间具备比较性,即自然顺序。
(重点)Map: 双列集合
特点:
键是唯一的
值可以重复的
Map集合体系关系
Map:
|- HashMap
|- TreeMap
Map集合中的方法:
添加功能:
V put(K key, V value)
删除功能:
void clear()
V remove(Object key)
判断功能:
boolean containsKey(Object key)
boolean containsValue(Object value)
boolean isEmpty()
获取功能:
Set> entrySet()
V get(Object key)
Set keySet()
Collection values()
长度功能:
int size()
(重点)HashMap:
特点:
底层:哈希表结构
如何保证HashMap集合中key是唯一的???
重写key 所对应的类中的 hashCode() 与 equals() 方法
注意: 如果 key 是API中提供的类,不需要自己重写,因为API已经重写好了, 而自己定义的类,必须要重写
(理解)TreeMap:
特点:
底层: 二叉树结构
如何保证TreeMao集合中的key 是唯一和排序的??
有两种方式:
方式1: 实现 自然排序接口
Comparable { compareTo(Object o) }
方式2: 实现 比较器接口
Comparator { compare(Object o1, Object o2) }
注意: 具体如何比较的代码 需要自己来实现
(重点)Map集合遍历的两种方式:
方式1: 键 找 值
a: 获取集合中所有的key
b: 获取到每一个key
c: 通过当前的key, 获取到对应的值 value
方式2: 键值对, 找键,找值
a: 获取集合中所有的键值对对象
b: 获取到每一个键值对对象
c: 通过键值对对象, 找键,找值
(了解)HashMap集合与 Hashtable集合的区别?
Hashtable:
是一个Map集合
它是一个线程同步的集合, 安全
键不能为null , 值不能为null
HashMap:
它是一个线程不同步的集合
键可以为null, 值可以为null
(了解)Collections: 集合工具类:
二分查找法:public static int binarySearch(List extends Comparable super T>> list,T key)
最大值:public static > T max(Collection extends T> coll)
最小值:public static > T min(Collection extends T> coll)
排序:public static > void sort(List list)
随机打乱:public static void shuffle(List> list)
反转:public static void reverse(List> list)
把线程不同步的集合,变成同步的集合:public static Collection synchronizedCollection(Collection c)
Arrays类:
此类包含用来操作数组(比如排序和搜索)的各种方法。里面都是静态方法。
如果指定数组引用为 null,则此类中的方法都会抛出 NullPointerException。
(1)静态方法摘要:
static List asList(T... a)
返回一个受指定数组支持的固定大小的列表。
注意:
A:该方法将一个数组变成集合后,不可以使用集合的增删方法,因为数组的长度是固定的!
如果增删,则发生UnsupportedOprationException(不支持操作异常)
特别注意!!不能使用集合的增删方法改变长度!!!
B:如果数组中的元素都是基本数据类型,则该数组变成集合时,会将该数组作为集合的一个
元素出入集合
C:如果数组中的元素都是对象,如String,那么数组变成集合后,数组中的元素就直接转成
集合中的元素
数组变集合以及集合变数组的对比:
(1)数组变集合:
方法:static List asList(T... a) 返回一个受指定数组支持的固定大小的列表。
好处:可以使用集合的思想和方法操作数组中的元素,数组是一个对象,但是数组中的功能很少
(2)集合变数组:
方法:Collction中的toArray方法
好处:可以限定对集合元素的操作,防止对集合的元素进行增删,因为数组长度是固定的。
(重点)Collections类和Arrays类的使用。
A:Collections
排序
二分查找
发转
B:Arrays
把数组变成字符串输出
排序
二分查找