每日一狗(田园犬西瓜瓜)
Collection继承于Iterable接口。Iterable定义了对象必须可遍历,可迭代
public interface Iterable<T> {
Iterator<T> iterator();
default void forEach(
Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
}
6
@FunctionalInterface // 函数式接口,提供lambda表达式写法
public interface Consumer<T>
元素可重复,无序
删除元素的二义性:当存储的数据是Integer时,你传一个3进去就是按照指定索引进行取出,但是传入的是一个(Integer)3
时候就是按照对象来进行删除,返回是否成功。
E remove(int index):
boolean remove(Object obj):
继承Collection接口,没有特殊方法,元素之间无序唯一
能够使用forEach结构遍历的必须要实现Iterable接口
package com.yang1;
import java.util.Iterator;
public class Test01 {
public static void main(String[] args) {
A1 a = new A1();
for(Object t:a) {
}
}
}
class A1 implements Iterable<Object> {
@Override
public Iterator<Object> iterator() {
return null;
}
}
扩容时计算容积
minCapacity= 需求最小容积
oldSize = 原始数组容积
newSize = oldSize*3/2 = 新算出来的容积
判定:算出来的newSize 满足minCapacity的最小容积
private int newCapacity(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); // 扩容50%
if (newCapacity - minCapacity <= 0) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
return Math.max(DEFAULT_CAPACITY, minCapacity);
if (minCapacity < 0) // 最大容积时在扩容就没了
throw new OutOfMemoryError();
return minCapacity;
}
// 新容积满足最小容积
return (newCapacity - MAX_ARRAY_SIZE <= 0)
? newCapacity // 小于最大容积值时返回
: hugeCapacity(minCapacity);
}
/15
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // 最大容积时在扩容就没了
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE)
? Integer.MAX_VALUE // 最小容积大于最大容积返回Integer.MAX_VALUE
: MAX_ARRAY_SIZE; //
}
public Vector(Collection<? extends E> c) {
elementData = c.toArray();
elementCount = elementData.length;
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
}
5 将指定数组中的数据中的多少个拷贝到指定类型的数据类型红枣年糕
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
@SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
扩容时获取新容积
private int newCapacity(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + ((capacityIncrement > 0) ? // 扩容步长大于0时按照步长扩容
capacityIncrement : oldCapacity); // 扩容步不大于0则使用100%比例扩容
if (newCapacity - minCapacity <= 0) { // 新容积不满足最小容积时
if (minCapacity < 0) // 所需容积是否溢出
throw new OutOfMemoryError();
return minCapacity; // 返回扩容长度为最小容积值
}
return (newCapacity - MAX_ARRAY_SIZE <= 0) // 如果计算出来的新值
? newCapacity // 返回新的容积
: hugeCapacity(minCapacity); //
}
13
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
解决问题:我在编码的时候也不确定我这个类型应该是什么类型
class A1<T>{ // 泛型类
T id;
void pp(T t){} // 泛型类的成员方法
}
静态方法中不可以使用泛型类中的泛型类,想用就必须在静态方法中再次声明泛型
<T> void pp(T t){} // 泛型实例成员方法
static <T> void dd(T t){} // 泛型静态方法
通配符 ?
上限 extends
下限 super
下限一般配合通配符不确定参数一起使用
实现了List接口,元素之间有序可重复。
ArrayList 和 Vector 的底层存储都是数组。
ArrayList、Vector
主要区别的是Vector的多数方法都是有synchronized修饰的,线程安全的;反之ArrayList线程不安全,并发效率高。
ArrayList的扩容比是1.5倍,而Vector可以设定固定的扩容步长capacityIncrement,在不设定时用的扩容比例是2.0。
扩容容积计算步骤:
- ArrayList和Vector扩容容积合法性判定基本一致,newCapacity(ke pai sei tei)新容积同时满足minCapacity最小容积和MAX_ARRAY_SIZE最大容积时返回newCapacity;
- newCapacity不满足minCapacity最小容积时,需要判定minCapacity的合法性。0
- 当newCapacity也不满足MAX_ARRAY_SIZE要求时,则此时的minCapacity已经相当巨大了,此时需要判定minCapacity应该考虑取用Integer.MAX_VALUE 和MAX_ARRAY_SIZE哪个合适,不管咋选都要最少>=minCapacity
注释:由于ArrayList存在延迟创建的机制,在第2步minCapacity合法性判定时需要多判定一个elementData是否为空数组,是则返回minCapacity和DEFAULT_CAPACITY之间的最大值。
0 > minCapacity 即当所需容积小于0时,当前容积为Integer.MAX_VALUE,在调用grow(size + 1)时数据已经溢出,数组索引使用整形,这里相当于已经数组已经满了,在插入数据会抛出内存溢出错误。
ArrayList在未指定或指定容积为0时会使用延迟创建的方式进行内存优化,Vector未指定容积时默认容积为10。
ArrayList、LinkedList
主要区别在于底层存储,ArrayList用数组进行存储,LinkedList底层存储使用的是双向链表。
在插入删除和检索时二者各有所长,ArrayList检索高效、LinkedList删除插入高效
Collection
相对于其余二者来说是顶级接口,自身继承于另一个更加抽象的接口Iterable
元素无序、可以重复。定义了一个容器应该满足的一些抽象方法元素的增删改查,容器的遍历,容器的导入与导出,容器清空等等
List
继承Collection,在Collection基础上引入了索引的概念,元素之间
Set