赞
踩
集合:
// 因为Conllection是接口,所以使用List接口下面的ArrayList来实现 List list = newArrayList(); // add:添加单个元素 list.add("jack"); list.add(10);//list.add(new Integer(10)) list.add(true); System.out.println("list=" + list); // remove:删除指定元素 //list.remove(0);//删除第一个元素 list.remove(true);//指定删除某个元素 System.out.println("list=" + list); // contains:查找元素是否存在 System.out.println(list.contains("jack"));//T // size:获取元素个数 System.out.println(list.size());//2 // isEmpty:判断是否为空 System.out.println(list.isEmpty());//F // clear:清空 list.clear(); System.out.println("list=" + list); // addAll:添加多个元素 ArrayList list2 = new ArrayList(); list2.add("红楼梦"); list2.add("三国演义"); list.addAll(list2); System.out.println("list=" + list); // containsAll:查找多个元素是否都存在 System.out.println(list.containsAll(list2));//T // removeAll:删除多个元素 list.add("聊斋"); list.removeAll(list2); System.out.println("list=" + list);//[聊斋]
Iterator iterator = coll.iterator(); //得到一个迭代器
while(iterator.hasNext(){ //hasNext() 判断是否还有下一个元素
System.out.println(iterator.next()); //next的作用:1.下移,2将下移以后集合位置上的元素返回
}
// void add(int index, Object ele):在 index 位置插入 ele 元素 //在 index = 1 的位置插入一个对象 list.add(1, "韩顺平"); // boolean addAll(int index, Collection eles):从 index 位置开始将 eles 中的所有元素添加进来 List list2 = new ArrayList(); list2.add("jack"); list2.add("tom"); list.addAll(1, list2); // Object get(int index):获取指定 index 位置的元素 // int indexOf(Object obj):返回 obj 在集合中首次出现的位置 System.out.println(list.indexOf("tom"));//2 // int lastIndexOf(Object obj):返回 obj 在当前集合中末次出现的位置 list.add("xixi"); System.out.println("list=" + list); System.out.println(list.lastIndexOf("xixi")); // Object remove(int index):移除指定 index 位置的元素,并返回此元素 list.remove(0); // Object set(int index, Object ele):设置指定 index 位置的元素为 ele , 相当于是替换. list.set(1, "玛丽"); System.out.println("list=" + list); // List subList(int fromIndex, int toIndex):返回从 fromIndex 到 toIndex 位置的子集合 // 注意返回的子集合 fromIndex <= subList < toIndex List returnlist = list.subList(0, 2); System.out.println("returnlist=" + returnlist
List list = new ArrayList();
list.add("飞飞");
list.add("李四");
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
for(Object o:list){
System.out.println(o);
}
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L;
// 默认容量
private static final int DEFAULT_CAPACITY = 10;
// 空数据
private static final Object[] EMPTY_ELEMENTDATA = {};
// 默认容量空数据
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
// 存储数据的数组
transient Object[] elementData;
// 数组大小
private int size;
//无参构造方法 public ArrayList() { //创建一个空数组 this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } //有参构造方法 public ArrayList(int initialCapacity) { //当初始容量<0,抛出异常 IllegalArgumentException if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } } public boolean add(E e) { //确保有足够的容量,假如你是5个,你必须得有6个容量才能保证你下一次能够加入 ensureCapacityInternal(size + 1); //这个size就是数组大小 //在数据中正确的位置上放上元素e,并且size++ elementData[size++] = e; return true; } //这是的 minCapacity 就是上面的 size+1, private void ensureCapacityInternal(int minCapacity) { //判断elementData是不是空的数组 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { // DEFAULT_CAPACITY = 10,上面定义了,这句话的意思就是把需要的最小容量和10进行比较,把最大值赋值给minCapacity minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); } private void ensureExplicitCapacity(int minCapacity) { modCount++; //判断elementData是否够用,不够进行扩容 if (minCapacity - elementData.length > 0) grow(minCapacity); } private void grow(int minCapacity) { int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); // 1.5倍扩容 if (newCapacity - minCapacity < 0)//如果扩大1.5倍还不行,则进行大容量分配 newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity); //最后将扩容后的长度复制给数组 } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
1.使用无参构造器
刚开始是创建一个elementData空数组
调用add方法确定是否进行扩容,调用ensureCapacityInternal方法把数组需要的最小容量传进去(minCapacity) (这里的minCapacity就是上面的size+1),这个size就是数组大小,初始为0
然后进行判断这个数组是否是个空的,然后将minCapacity和默认容量10进行比较,把最大值赋值给minCapactity
然后执行ensureExplicitCapacity(minCapacity)方法,再进行比较,
如果需要的最小容量还是比数组长度大,就调用grow(minCapacity)方法进行扩容,1.5扩容(第一次是10,第二次开始就是1.5倍),
最后将扩容后的长度复制给数组
2.使用有参构造器
刚开始就是创建一个指定大小容量的数组,后面和上面的一样
jdk1.7不同的就是
1.7类似单例的饿汉式(管你要不要,直接给你)
1.8类似单例的懒汉式(你需要就给你) 延迟了数组的创建,节省内存。
无参构造:刚开始就是一个长度为10 的数组
有参构造:指定的容量必须>10,否则抛出异常
扩容的时候,减少了ensureExplicitCapacity(minCapacity)方法,在ensureCapacityInternal方法中不再判断数组是否为空,直接进行扩容(之前是在ensureExplicitCapacity(minCapacity)方法中进行扩容的)
底层也是数组,线程都是安全的
public synchronized boolean add(E e) { modCount++; //增加元素前,检查容量是否够用 ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = e; return true; } // minCapacuty = elementCont +1 private void ensureCapacityHelper(int minCapacity) { // minCapacity就是最小需要的容量 if (minCapacity - elementData.length > 0) // 最小需要的容量都比数组长度大,就进行扩容 grow(minCapacity); } //扩容 private void grow(int minCapacity) { int oldCapacity = elementData.length; // capacityIncrement 容量增量 // 如果增量>0就增长 capacityIncrement 长度,否则 2倍扩容 int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity); //最后把扩容后的长度复制给数组 }
底层是一个HashMap,非线程安全,初始化容量是16,2倍扩容,默认加载因子 0.75 (意思就是说,当数组的个数到达容量的0.75
时,就会进行扩容)
Java8中,如果一条链表的元素个数到达8个并且table>=64,就会进行树化(红黑树),否则仍然采用数组扩容机制
key 和value 都允许null
Java8之前使用拉链法,底层使用数组+链表,8之后 底层使用数组+链表+红黑树
HashMap是基于哈希算法来确定元素的位置(槽)的,当我们向集合中存入数据时,它会计算传入的Key的哈希值,并利用哈希值取余来确定槽的位置。如果元素发生碰撞,也就是这个槽已经存在其他的元素了,则HashMap会通过链表将这些元素组织起来。如果碰撞进一步加剧,某个链表的长度达到了8,则HashMap会创建红黑树来代替这个链表,从而提高对这个槽中数据的查找的速度。
HashMap中,数组的默认初始容量为16,当数组中的元素达到一定比例的时候HashMap就会2倍扩容,这个比例叫做负载因子,默认为0.75。自动扩容机制,是为了保证HashMap初始时不必占据太大的内存,而在使用期间又可以实时保证有足够大的空间。采用2的指数进行扩容,是为了利用位运算,提高扩容运算的效率
首先会先判断该数组是否为null,如果为空进行扩容,然后根据key计算hash值,得到插入的位置,
如果该位置为空,直接进行插入,否则就判断key是否相等,如果相等直接进行覆盖,
不相等就判断它是否为红黑树,如果是红黑树就直接在树中进行插入,
否则就遍历链表,遍历的过程中,若发现key相等就进行覆盖,
不相等就判断链表长度是否>8,如果>8就把链表转换为红黑树,在树中进行插入,
插入成功后再判断是否超过了阈(域)值,超过了就进行扩容,没有就结束。
1. 如果数组为空,则进行首次扩容。
2. 将元素接入链表后,如果链表长度达到8,并且数组长度小于64,则扩容。
3. 添加元素后,如果数组中元素超过阈值,也就是加载因子0.75就进行扩容
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。