Day08 集合
1.数据结构
是用来研究如何存储数据的,也就是研究存储数据的方式的。
常见的数据结构:
1.数组:
使用一段连续的内存空间来存储一组数据,相邻的两个元素的地址是挨着的;
第一个元素的地址(首地址)就是数组的地址;
计算元素的地址的公式:数组的地址+索引*每个元素占用的空间大小;
特点: 查询和修改数据速度快;删除速度比较慢;
2.链表:
不是使用一组连续的内存空间存储数据的,相邻的两个数据的地址可以不是挨着的;
在前一个元素中记录下一个元素的地址,可以通过两个元素中的地址找到下一个元素;
特点: 查询和修改的速度慢;增删数据的速度快;
3.哈希表:
使用一张表和复杂的算法来存储一组数据的;
特点: 如果hash表中使用纯数组存储数据,hash算法查询数据的速度是最快的;存储的顺序不一定是你添加的顺序;
4.队列
特点: 先进先出;
5.栈
先压入到栈中的元素存放在栈底;
后压入的元素存放在栈顶;
位于栈顶的元素最先弹出栈,位于栈底的元素最后出栈;
2.LinkedList类
LinkedList集合数据存储结构是链表式结构;
操作头尾节点的方法:
viod addFirst(E e) :在链表的第一个节点位置添加一个新元素;
viod addLast(E e) :在链表的最后一个节点位置添加一个新元素;
E getFirst():得到第一个元素;
E getLast():得到最后一个元素;
E pop():弹栈,取出栈定的元素;
void push(E e):向栈中添加一个新的元素;
应用场景:
1.当查询的情况比较多的时候,使用ArrayList集合;
2.添加和删除的情况比较多时,使用LinkedList集合;
3.当不能区分查询和添加,删除的情况那个多时,就使用ArrayList;
3.set接口
Set集合有多个子类,主要介绍HashSet、LinkedHashSet集合;
Set与List的区别:
1.list集合中存储的元素的顺序与添加元素的顺序是一致的,set集合中存储元素的顺序和添加元素的顺序不一定是一致的;
2.list集合中可以存储重复的元素,set集合中不能存储重复的元素;
Set接口中的方法都是从Collection接口中继承过来,没有特有的方法;
实现类:
HashSet类
LinkedHashSet类
4.ArrayList和HashSet 的add 方法的区别:
1.ArrayList的add方法:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
永远返回true,永远添加成功,没有判断是否重复,可以添加重复的元素.
2.HashSet 的add 方法
不能添加重复的元素,判断两个元素是否重复时调用了 hashCode()方法和equals方法;
1. 源代码:
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
2.调用hashmap的put方法:
public V put(K key, V value) {
...
// 得到元素的地址
int hash = hash(key);
// 得到元素在hashset集合中的索引位置
int i = indexFor(hash, table.length);
for (在集合中查找相同的元素 e) {
// 判断两个对象是否一样:
// 1.地址要一样;
// 2.内容要一样;
if (e.hash == hash && ( key.equals(k)) {
// 返回已经存在的元素
return oldValue;
}
}
// 如果没有重复的元素
// 集合的大小加1
modCount++;
// 把元素添加到集合中
addEntry(hash, key, value, i);
// 添加成功后返回null
return null;
}
3.调用hash方法:
得到元素的地址
final int hash(Object k) {
...
// 得到元素的地址
h = k.hashCode();
...
return h;
}
4.ArrayList集合判断元素是否唯一
contains方法:
只调用equals方法来判断的;
1. 源代码:
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
2. 调用indexOf()方法:
如果在集合中找到了一样的元素就返回元素的索引;
如果没找到就返回-1;
public int indexOf(Object o) {
if (o == null) {
...
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
5.HashSet集合判断元素是否唯一
contains方法:
使用两个方法判断元素是否重复:
equals方法和hashCode方法:
1.源代码:
public boolean contains(Object o) {
return map.containsKey(o);
}
2.调用了hashMap的containsKey方法:
public boolean containsKey(Object key) {
return getEntry(key) != null;
}
3.调用Hashmap的getEntry方法:
final Entry<K,V> getEntry(Object key) {
if (size == 0) {
return null;
}
// 得到传进来的那个数据的地址
int hash = hash(key);
// 得到传进来的那个数据在hashset中第一次出现的索引位置
int i = indexFor(hash, table.length);
for (得到重复的那个元素 e) {
Object k;
if (e.hash == hash && key.equals(k))
return e;
}
return null;
}
4.调用hash方法:
得到元素的地址
final int hash(Object k) {
...
// 得到元素的地址
h = k.hashCode();
...
return h;
}