2020 10.29曾宇欣
心得体会:
前端的东西已经遗忘的差不多了,急需回忆。tomcat的使用也不熟悉,还需要多了解。
知识点:
今日复习:
一、集合:
java
中针对数组的缺陷(不可修改长度),提供了一种比数组灵活,使用更方便的接口和类,它们位于 java.until
包,称为集合框架
-
java.lang.Iterable
Iterable 接口,凡是实现了此接口的对象都能称为 for-each-loop 的目标。
此接口会在之后单独总结
-
java.util.Collection
public interface Collection<E> extends Iterable<E>
从类声明中我们可以看到,Collection接口继承了Iterable接口。意味着Collection接口的类也实现了Iterable接口,可以成为for-each-loop的循环对象。
-
Collection集合的方法:
public boolean add(E e) //在集合末尾添加元素 public boolean remove(Object o) //若本类集合中有值与o相等,则删除该元素
public void clear() //清除本类集合中的所有元素,集合为空
public contains(Object o) //判断集合中是否包含某元素
public boolean isEmpty() //判断集合是否为空
public int size() //返回集合中的元素个数
public Boolean addAll(Collection c) //将一个集合c中的元素,全部添加到另一个集合中去
public Object[] toArray() //返回一个包含本类集合中的所有元素的数组,数组类型为,Object[]
-
-
Collection 之ArrayList:
-
ArrayList是实现List接口的动态数组,数组大小可变。
-
ArrayList允许存储null在内的所有元素
-
ArrayList的初始容量是 10 ,并且容量会自动增长,在每次添加元素的时候,ArrayList会自动检查是否需要扩容,扩容操作带来数据向新数组的重新拷贝。如果我们知道具体业务的数量,在构造ArrayList的时候给它指定一个初始长度,这样就会减少扩容时数据的拷贝问题。
-
ArrayList是非线程安全的
ArrayList的构造函数
ArrayList() //默认构造函数 ArrayList(int initialCapacity) //构造一个具有指定初始容量的空列表
ArrayList(Collection<? extends E> c) //构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的ArrayList添加元素操作:
add(E e) //将指定元素添加到末尾 //源码分析
public boolean add(E e) {
ensureCapacity(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
//这里ensureCapacity()方法是对ArrayList集合进行扩容操作,elementData(size++) = e,将列表末尾元素指向e。add(int index, E element) //将指定元素插入此列表的指定位置 public void add(int index, E element) {
//判断索引位置是否正确
if (index > size || index < 0)
throw new IndexOutOfBoundsException(
"Index: "+index+", Size: "+size);
//扩容检测
ensureCapacity(size+1);
/*
* 对源数组进行复制处理(位移),从index + 1到size-index。
* 主要目的就是空出index位置供数据插入,
* 即向右移动当前位于该位置的元素以及所有后续元素。
*/
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
//在指定位置赋值
elementData[index] = element;
size++;
}addAll(Collection<? extends E> c)://按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的尾部。 public boolean addAll(Collection<? extends E> c) {
// 将集合C转换成数组
Object[] a = c.toArray();
int numNew = a.length;
// 扩容处理,大小为size + numNew
ensureCapacity(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}addAll(int index, Collection<? extends E> c)://从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。 public boolean addAll(int index, Collection<? extends E> c) {
//判断位置是否正确
if (index > size || index < 0)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: "
+ size);
//转换成数组
Object[] a = c.toArray();
int numNew = a.length;
//ArrayList容器扩容处理
ensureCapacity(size + numNew); // Increments modCount
//ArrayList容器数组向右移动的位置
int numMoved = size - index;
//如果移动位置大于0,则将ArrayList容器的数据向右移动numMoved个位置,确保增加的数据能够增加
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
//添加数组
System.arraycopy(a, 0, elementData, index, numNew);
//容器容量变大
size += numNew;
return numNew != 0;
}set(int index, E element)://用指定的元素替代此列表中指定位置上的元素。 public E set(int index, E element) {
//检测插入的位置是否越界
RangeCheck(index);
E oldValue = (E) elementData[index];
//替代
elementData[index] = element;
return oldValue;
}ArrayList的删除操作:
remove(int index)://移除此列表中指定位置上的元素。 public E remove(int index) {
//位置验证
RangeCheck(index);
modCount++;
//需要删除的元素
E oldValue = (E) elementData[index];
//向左移的位数
int numMoved = size - index - 1;
//若需要移动,则想左移动numMoved位
if (numMoved > 0)
System.arraycopy(elementData, index + 1, elementData, index,
numMoved);
//置空最后一个元素
elementData[--size] = null; // Let gc do its work
return oldValue;
}remove(Object o)://移除此列表中首次出现的指定元素(如果存在)。 public boolean remove(Object o) {
//因为ArrayList中允许存在null,所以需要进行null判断
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
//移除这个位置的元素
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}removeRange(int fromIndex, int toIndex)://移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。 protected void removeRange(int fromIndex, int toIndex) {
modCount++;
int numMoved = size - toIndex;
System
.arraycopy(elementData, toIndex, elementData, fromIndex,
numMoved);
// Let gc do its work
int newSize = size - (toIndex - fromIndex);
while (size != newSize)
elementData[--size] = null;
}ArrayList的扩容操作:
在上面的新增方法的源码中我们发现每个方法中都存在这个方法:ensureCapacity(),该方法就是ArrayList的扩容方法。在前面就提过ArrayList每次新增元素时都会需要进行容量检测判断,若新增元素后元素的个数会超过ArrayList的容量,就会进行扩容操作来满足新增元素的需求。所以当我们清楚知道业务数据量或者需要插入大量元素前,我可以使用ensureCapacity来手动增加ArrayList实例的容量,以减少递增式再分配的数量。
public void ensureCapacity(int minCapacity) { //修改计时器
modCount++;
//ArrayList容量大小
int oldCapacity = elementData.length;
/*
* 若当前需要的长度大于当前数组的长度时,进行扩容操作
*/
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
//计算新的容量大小,为当前容量的1.5倍
int newCapacity = (oldCapacity * 3) / 2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
//数组拷贝,生成新的数组
elementData = Arrays.copyOf(elementData, newCapacity);
}
}选择扩容1.5倍是因为,1.5倍是最好的倍数,对资源利用率最高
-
List的三个子类的特点:
ArrayLIst的底层数据结构是数组,查询块,增删慢。非线程安全,效率高。
Vector的底层数据结构是数组,查询快,增删慢。线程安全,效率低。
Vector相对于ArrayList查询效率低,相对于LinkedList增删慢。
LinkedList底层数据结构是链表,查询慢,增删快。非线程安全,效率高。
查询多使用ArrayList
增删多使用LinkedList
都多使用ArrayList
一、HashSet定义:
public class HashSet<E> extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.SerializableHashSet继承AbstractSet类,实现Set、Cloneable、Serializable接口。其中AbstractSet提供 Set 接口的骨干实现,从而最大限度地减少了实现此接口所需的工作。Set接口是一种不包括重复元素的Collection,它维持它自己的内部排序,所以随机访问没有任何意义。
二、方法:
// iterator()方法返回对此 set 中元素进行迭代的迭代器。返回元素的顺序并不是特定的。底层调用HashMap的keySet返回所有的key,这点反应了HashSet中的所有元素都是保存在HashMap的key中,value则是使用的PRESENT对象,该对象为static final。 public Iterator<E> iterator() {
return map.keySet().iterator();
}
//size() 返回set中元素的数量
public int size(){}
//判断HashSet是否为空
public boolean isEmpty(){}
//判断某个元素是否在HashSet中
public boolean contains(Object o){}
//移除指定元素
public boolean remove(Object o){}
//移除HashSet中的所有元素
public void clear(){}由于HashSet底层使用了HashMap实现
近期评论