学习笔记17.集合框架
集合框架
集合概念
一:概念
对象的容器,实现了对对象常用的操作,类似数组的功能。
二:集合和数组的区别
- 数组长度固定,集合长度不固定。
- 数组可以存储基本类型和引用类型,集合只能存储引用类型。
位置:java.util.*
Collection体系集合

Collection父接口
特点:代表一组任意类型的对象,无序、无下标、不能重复。
常用方法:
- boolean add(Object obj) //添加一个对象。
- boolean addAll(Collection c) //将一个集合中的所有对象添加到此集合中。
- void clear() //清空此集合中的所有对象。
- boolean contains(Object o) //检查此集合中是否包含o对象。
- boolean equals(Object o) //比较此集合是否与指定对象相等。
- boolean isEmpty() //判断此集合是否为空。
- boolean remove(Object o) //在此集合中移除o对象
- int size() //返回此集合中的元素个数。
- Object[] toArray() //将此集合转换成数组。
迭代器:
创建迭代器:
Iterator it = collection.iterator();
方法:
- hasNext();判断有没有下一个元素。
- next();获取下一个元素。
- remove();删除当前元素。
注意:迭代过程中不能使用collection删除方法。
List接口
特点:有序、有下标、元素可以重复。
方法:
- void add(int index,Object 0) //在index位置插入对象o。
- boolean addAll(int index,Collection c) //将一个集合中的所有元素添加到此集合中的index位置。
- Object get(int index) //返回集合中指定位置的元素。
- List subList(int fromIndex,int toIndex) //返回fromIndex和toIndex之间的集合元素(含头不含尾)。
- int indexOf(Object o)返回对象o在集合中第一次出现的脚标。
迭代器:
ListIterator可以向前或向后遍历,添加、删除、修改元素。
创建迭代器:
ListIterator lit = list.listIterator();
注意:
- 集合中删除数字元素时要注意remove方法中要传入Object类型或Integer类型,如果直接传入int类型,则会判定为角标。
List实现类
ArrayList【重点】:
- 数组结构实现,查询快、增删慢;
- JDK1.2版本,运行效率快,线程不安全。
源码分析:
-
DEFAULT_CAPACITY = 10; 默认容量
注意:如果没有向集合中添加任何元素时,容量为0,添加一个任意元素之后,容量为10。
每次扩容扩容为原来的1.5倍。
-
elementDate 用来存放元素的数组。
-
size 实际的元素个数。
-
add() 添加元素。
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
Vector:
- 数组结构实现,查询快、增删慢;
- JDK1.0版本,运行效率慢、线程安全。
枚举器:
创建枚举器:
Enumeration en = vector.elements();
方法:
- hasMoreElements() 判断是否有下一个元素。
- nextElement() 取出下一个元素。
- firstElement、lastElement、elementAt();
LinkedList:
- 链表结构实现,增删快,查询慢。
源码分析:
int size:集合的大小。
Node first;链表的头节点
Node last;链表的尾节点
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
ArrayList和LinkedList区别

泛型
泛型概述:
Java泛型时JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递。
常见形式有泛型类、泛型接口、泛型方法。
语法:
- <T,...> T称为类型占位符,表示一种引用类型。
好处:
- 提高代码的重用性。
- 防止类型转换异常,提高代码安全性。
泛型类:
语法:类名<T>,T是类型占位符,表示一种引用类型,如果编写多个使用逗号隔开。
注意:
- 泛型只能使用引用类型
- 不同泛型类型对象之间不能互相赋值。
- 泛型类中不能使用T创建对象。
泛型接口
语法:接口名<T>,T是类型占位符,表示一种引用类型,如果编写多个使用逗号隔开。
注意:不能创建泛型静态常量。
泛型方法
语法:<T> 返回值类型
注意:T的类型会自动变为方法参数传入值的类型。
泛型集合:
概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致。
特点:
- 编译时即可检查,而非运行时抛出异常。
- 访问时,不必类型转换(拆箱)。
- 不同泛型之间引用不能互相赋值,泛型不存在多态。
Set子接口
特点:无序、无下标、元素不可重复。
方法:全部继承自Collection中的方法。
Set实现类
HashSet【重点】:
存储结构:哈希表(数组+链表+红黑树)
特点:
- 基于HashCode计算元素存放位置。
- 当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入。
存储过程:
- 根据hashcode,计算保存的位置。如果此位置为空,则直接保存,如果不为空,执行第二部。
- 再执行equals方法,如果equals方法为true,则认为时重复元素,否则,形成链表。
TreeSet
存储结构:红黑树
要求:元素必须要实现Comparable接口,compareTo()的返回值为0,认为是重复元素。
Comparator接口:实现定制比较(比较器)
小案例:
//要求:使用TreeSet集合实现字符串按照长度进行排序。
public static void main(String[] args) {
//创建集合,并指定比较规则
TreeSet<String> treeSet = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int n1 = o1.length()-o2.length();
int n2 = o1.compareTo(o2);
return n1==0?n2:n1;
}
});
//添加数据
treeSet.add("helloWorld");
treeSet.add("pingguo");
treeSet.add("zhangsan");
treeSet.add("beijing");
treeSet.add("cat");
treeSet.add("nanjing");
treeSet.add("xian");
//输出
System.out.println(treeSet.toString());
Map体系集合

Map父接口
特点:存储键值对(Key-Value),无序,无下标,键不可重复,值可重复。
方法:
- V put(K key,V value) //将对象存入到集合中,关联键值。key重复则覆盖原值。
- Object get(Object key) //根据键值获取对应的值。
- keySet() //返回此地图中包含的键的Set视图。
- Collection<V> values() //返回包含所有值的Collection集合。
- entrySet //返回此地图中包含的映射的Set视图。
HashMap【重点】:
JDK1.2版本,线程不安全,运行效率快;允许用null作为key或是value。
存储结构:哈希表(数组+链表+红黑树),使用key的hashcode和equals作为重复。
源码分析:
属性:
1. static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // hashMap初始容量大小
2. static final int MAXIMUM_CAPACITY = 1 << 30; //hashMAp的数组最大容量
3. static final float DEFAULT_LOAD_FACTOR = 0.75f; //默认加载因子,每次扩容长度为原来的2倍。
4. static final int TREEIFY_THRESHOLD = 8; //jdk1.8当链表长度大于8,会把链表替换为红黑树。
5. static final int UNTREEIFY_THRESHOLD = 6;//jdk1.8当链表长度小于6,把红黑树替换为链表。
6. static final int MIN_TREEIFY_CAPACITY = 64;//jdk1.8当链表长度大于8,数组长度大于等于64,调整为红黑树
7. transient Node<K,V>[] table;//哈希表中的数组
8. size;//元素个数
无参构造:
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}
刚创建hashMap之后没有添加元素 table=null size=0 目的:节省空间
put方法
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
总结:
- HashMap刚创建时table时null,为了节省空间。当添加第一个元素时,table容量调整为16。
- 当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容大小为原来的两倍。目的是减少调整元素的个数。
- jdk1.8 当每个链表长度大于8,并且元素个数大于等于64时,会调整为红黑树,目的是提高执行效率。
- jdk1.8 当链表长度小于6时,调整为链表。
- jdk1.8以前,链表从头插入,jdk1.8以后是从尾插入。
TreeMap
实现了SortedMap接口,可以对key自动排序。
存储结构:红黑树
要求:元素必须要实现Comparable接口,compareTo()的返回值为0,认为是重复元素。
Comparator接口:实现定制比较(比较器)
Colletions工具类
概念:集合工具类,定义了除了存取以外的集合常用方法。
方法:
- reverse()//反转集合
- shuffle()//随机重置集合元素顺序
- sort() //升序排序(元素必须实现Comparable接口)
- copy() // 复制集合(两个集合大小必须一致)
总结


浙公网安备 33010602011771号