注:详解核心源码 = 逐句解释源码 + 分情况举例说明 + 必要辅助图解
目录
Collection体系
Collection体系 注意事项
- List接口:有序(指添加的顺序和遍历的顺序是一致的)、有下标、元素可重复。
- Set接口:无序(指添加的顺序和遍历的顺序是不一致的)、无下标、元素不能重复。
Collection父接口
Collection方法
Collection案例实现
public class CollectionTest {
public static void main(String[] args) {
Collection collection=new ArrayList();
System.out.println("-----isEmpty------");
//isEmpty 判断集合是否有元素,有返回true,没有返回false
System.out.println(collection.isEmpty());
System.out.println("-----add------");
//add 往集合中添加元素
Student s1=new Student("张三",18);
Student s2=new Student("李四",19);
Student s3=new Student("王五",20);
Student s4=new Student("孙六",21);
Student s5=new Student("赵七",22);
collection.add(s1);
collection.add(s2);
collection.add(s3);
collection.add(s4);
collection.add(s5);
System.out.println(collection);
System.out.println("-----size------");
//size 返回集合中元素个数
System.out.println(collection.size());
System.out.println("-----remove------");
collection.remove(s3);
System.out.println(collection);
System.out.println("------removeAll-----");
//colletion.removeAll(Collection C)
//从collection中删除那些也包含在C中的所有元素
Student s6=new Student("刘八",23);
Collection collection2=new ArrayList();
collection2.add(s4);
collection2.add(s6);
collection.removeAll(collection2);
System.out.println(collection);
System.out.println("------retainAll-----");
//colletion.retainAll(Collection C)
//仅保留collection中那些也包含在C的元素
//没有一个交集返回true,有交集但不全交也返回true,而两个集合相等的时候,返回false
Student s7=new Student("林九",24);
Collection collection3=new ArrayList();
collection3.add(s7);
collection3.add(s1);
collection3.add(s2);
System.out.println(collection);
System.out.println("有交集:"+collection.retainAll(collection3));
Collection none=new ArrayList();
Collection test=new ArrayList();
test.addAll(collection);
System.out.println("没有交集:"+test.retainAll(none));
test.addAll(collection);
System.out.println("两个集合相等:"+test.retainAll(test));
System.out.println("------contains-----");
//contains 是否包含该元素 是返回true 不是返回false
System.out.println(collection.contains(s2));
//如果conrtains(新的对象) 那么就相当于开辟了新的空间,与原来的s2不同
System.out.println(collection.contains(new Student("李四",19)));
System.out.println("------containsAll-----");
//colletion.containsAll(Collection C)
//若collection包含T所有元素返回true,反之返回false
Collection collection4=new ArrayList();
collection4.add(s1);
System.out.println(collection.containsAll(collection4));
System.out.println("------equals and hashcode-----");
//equals 判断两个集合的每个元素的地址是否相等
System.out.println(collection);
Collection collection5=new ArrayList();
collection5.add(s1);
collection5.add(new Student("李四",19));
Collection collection6=new ArrayList();
collection6.add(s1);
collection6.add(s2);
System.out.println("collection"+collection.hashCode());
System.out.println("collection5"+collection5.hashCode());
System.out.println("collection6"+collection6.hashCode());
System.out.println(collection.equals(collection5));
System.out.println(collection.equals(collection6));
System.out.println("------addAll-----");
//colletion.addAll(Collection C)
//colletion中添加C中所有元素
collection.addAll(collection2);
System.out.println(collection);
System.out.println("------遍历-----");
//1.增强for遍历
for (Object o : collection) {
Student stu=(Student) o;
System.out.printf("%s ",stu.getName());
}
System.out.printf("\n");
//2.迭代器遍历
Iterator it=collection.iterator();
while (it.hasNext()){
Student student = (Student) it.next();
System.out.printf("%s ",student.getName());
if (student.getName().equals("刘八")){
it.remove();
}
}
System.out.printf("\n");
System.out.println(collection);
System.out.println("------toArray-----");
//toArray() 将集合变为数组
//toArray(T []) 将集合变为指定T数组
Student[] t=new Student[5];
Student[] arr = (Student[]) collection.toArray(t);
for (Student student : arr) {
if (student!=null){
System.out.printf("%s ",student.getName());
}
}
System.out.printf("\n");
System.out.println("------clear-----");
//clear清空集合元素
System.out.println(collection);
collection.clear();
System.out.println(collection.size());
}
}
class Student{
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
//输出结果:
-----isEmpty------
true
-----add------
[Student{name='张三', age=18}, Student{name='李四', age=19}, Student{name='王五', age=20}, Student{name='孙六', age=21}, Student{name='赵七', age=22}]
-----size------
5
-----remove------
[Student{name='张三', age=18}, Student{name='李四', age=19}, Student{name='孙六', age=21}, Student{name='赵七', age=22}]
------removeAll-----
[Student{name='张三', age=18}, Student{name='李四', age=19}, Student{name='赵七', age=22}]
------retainAll-----
[Student{name='张三', age=18}, Student{name='李四', age=19}, Student{name='赵七', age=22}]
有交集:true
没有交集:true
两个集合相等:false
------contains-----
true
false
------containsAll-----
true
------equals and hashcode-----
[Student{name='张三', age=18}, Student{name='李四', age=19}]
collection-1492222893
collection5-1698792011
collection6-1492222893
false
true
------addAll-----
[Student{name='张三', age=18}, Student{name='李四', age=19}, Student{name='孙六', age=21}, Student{name='刘八', age=23}]
------遍历-----
张三 李四 孙六 刘八
张三 李四 孙六 刘八
[Student{name='张三', age=18}, Student{name='李四', age=19}, Student{name='孙六', age=21}]
------toArray-----
张三 李四 孙六
------clear-----
[Student{name='张三', age=18}, Student{name='李四', age=19}, Student{name='孙六', age=21}]
0
值得注意:Collection的equals方法并没有重写
class Fruit{
private String name;
private String color;
public Fruit(String name, String color) {
this.name = name;
this.color = color;
}
}
public class ArrayListTest {
public static void main(String[] args) {
System.out.println("------Collection-------");
Collection c1=new ArrayList();
Fruit apple=new Fruit("苹果","red");
c1.add(apple);
Collection c2=new ArrayList();
c2.add(new Fruit("苹果","red"));
System.out.println(c1.equals(c2));
System.out.println(c1.hashCode()+" | "+c2.hashCode());
System.out.println("------Collection(String)-------");
Collection c3=new ArrayList();
Collection c4=new ArrayList();
c3.add(new String("Hello"));
c4.add(new String("Hello"));
System.out.println(c3.equals(c4));//返回true,因为字符串的比较重写了equals方法
}
}
//输出结果:
------Collection(obj)-------
false
1554874533 | 1846274167
------Collection(String)-------
true
List接口
List方法
List案例实现
public class ListTest {
public static void main(String[] args) {
List list= new ArrayList();
list.add(20);//添加基本类型会自动装箱
list.add(40);
list.add(50);
System.out.println(list);
System.out.println("-----add(int,E)-----");
list.add(1,60);
System.out.println(list);
System.out.println("-----addAll(int,E)-----");
List list2= new ArrayList();
list2.add(20);
list2.add(80);
list.addAll(2,list2);
System.out.println(list);
System.out.println("-----remove(int)-----");
list.remove(2);
System.out.println(list);
System.out.println("-----get(int)-----");
System.out.println(list.get(2));
System.out.println("-----set(int,E)-----");
list.set(1,50);
System.out.println(list);
System.out.println("-----lastIndexOf/indexOf(Object)-----");
System.out.println(list.indexOf(50));
System.out.println(list.lastIndexOf(50));
System.out.println("-----遍历-----");
//1.增强for 2.iterator迭代器 继承Collection,这两个方法遍历一样
//3.for循环
for (int i=0;i<list.size();i++){
System.out.printf("%d ",list.get(i));
}
System.out.println();
//4.使用列表迭代器,和iterator的区别,listIterator可以向前或向后遍历添加删除修改元素
ListIterator listIterator = list.listIterator();
while (listIterator.hasNext()){
System.out.printf("[%d]:%d ",listIterator.nextIndex(),listIterator.next());
}
System.out.println();
while (listIterator.hasPrevious()){
System.out.printf("[%d]:%d ",listIterator.previousIndex(),listIterator.previous());
}
}
}
//输出结果:
[20, 40, 50]
-----add(int,E)-----
[20, 60, 40, 50]
-----addAll(int,E)-----
[20, 60, 20, 80, 40, 50]
-----remove(int)-----
[20, 60, 80, 40, 50]
-----get(int)-----
80
-----set(int,E)-----
[20, 50, 80, 40, 50]
-----lastIndexOf/indexOf(Object)-----
1
4
-----遍历-----
20 50 80 40 50
[0]:20 [1]:50 [2]:80 [3]:40 [4]:50
[4]:50 [3]:40 [2]:80 [1]:50 [0]:20
ArrayList实现类
ArrayList方法及案例实现
public class ArrayListTest {
public static void main(String[] args) {
ArrayList arr=new ArrayList();
Fruit apple=new Fruit("苹果","red");
Fruit banana=new Fruit("香蕉","yellow");
Fruit orange=new Fruit("橙子","orange");
arr.add(apple);
arr.add(banana);
arr.add(orange);
System.out.println("------集合中存的是对象的引用-------");
apple.setName("大苹果");
System.out.println("添加进集合之后再改变apple的名字");
System.out.println(arr);
//添加元素 和List的方法一样,此处不再赘述
System.out.println("------remove(obj)-------");
//删除元素 remove源码中其实是调用了equals方法。主要是比较两者的地址
//如果重写Fruit的equals方法之后,就是比较两者的内容了
arr.remove(new Fruit("橙子","orange"));
System.out.println(arr);
System.out.println("------遍历-------");
//1.增强for 2.iterator迭代器 3.listIterator列表迭代器 4.for
//列表逆序 先将指针移动到尾部,然后从尾部向头部遍历
ListIterator listIterator = arr.listIterator();
while (listIterator.hasNext()){
listIterator.next();
}
while(listIterator.hasPrevious()){
Fruit f=(Fruit) listIterator.previous();
System.out.printf("%s ",f.toString());
}
System.out.println();
System.out.println("------contains(obj)-------");
System.out.println(arr.contains(new Fruit("香蕉","yellow")));
System.out.println("------indexOf(obj)-------");
System.out.println(arr.indexOf(new Fruit("香蕉","yellow")));
}
}
//输出结果:
------集合中存的是对象的引用-------
添加进集合之后再改变apple的名字
[Fruit{name='大苹果', color='red'}, Fruit{name='香蕉', color='yellow'}, Fruit{name='橙子', color='orange'}]
------remove(obj)-------
[Fruit{name='大苹果', color='red'}, Fruit{name='香蕉', color='yellow'}]
------遍历-------
Fruit{name='香蕉', color='yellow'} Fruit{name='大苹果', color='red'}
------contains(obj)-------
true
------indexOf(obj)-------
1
ArrayList的数据结构
- 分析一个类的时候,数据结构往往是它的灵魂所在,理解底层的数据结构其实就理解了该类的实现思路,具体的实现细节再具体分析。ArrayList底层的数据结构就是数组,数组元素类型为Object类型,即可以存放所有类型数据。我们对 ArrayList类的实例的所有的操作底层都是基于数组的。
ArrayList的源码分析(JDK1.8)
继承结构和层次关系
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
......
}
为什么要先继承AbstractList,而让AbstractList先实现List?而不是让ArrayList直接实现List?
- 这里是有一个思想,接口中全都是抽象的方法,而抽象类中可以有抽象方法,还可以有具体的实现方 法,正是利用了这一点,让AbstractList是实现接口中一些通用的方法,而具体的类,如ArrayList就继承这个AbstractList类,拿到一些通用的方法,然后自己在实现一些自己特有的方法,这样一来,让代码更简洁,就继承结构最底层的类中通用的方法都抽取出来,先一起实现了,减少重复代码。所以一般看到 一个类上面还有一个抽象类,应该就是这个作用。
ArrayList实现了哪些接口
- List接口:部分人解释是为了查阅代码方便。
- RandomAccess接口:用来快速随机存取, 有关效率的问题,在实现了该接口的话,那么使用普通的for循环来遍历,性能更高。
- Cloneable接口:实现了该接口,就可以使用Object.Clone()方法了。
- Serializable接口:
- 实现该序列化接口,表明该类可以被序列化,什么是序列化?简单的说,就是能够从类变成字节流传输,然后还能从字节流变成原来的类。
类中的属性
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
/**
* 版本号
*/
private static final long serialVersionUID = 8683452581122892189L;
/**
* 默认初始容量
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 空对象数组
* Shared empty array instance used for empty instances.
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* 初始对象数组
* Shared empty array instance used for default sized empty instances. We
* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
* first element is added.
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
* 元素数组
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
*/
transient Object[] elementData; // non-private to simplify nested class access
/**
* 实际元素大小,默认为0
* The size of the ArrayList (the number of elements it contains).
* @serial
*/
private int size;
}
构造方法
无参构造 ArrayList()
//Constructs an empty list with an initial capacity of ten.
//构造一个空的列表,初始容量为10
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
有参构造 ArrayList(int initialCapacity)
//Constructs an empty list with the specified initial capacity.
//构造一个空的列表,自定义初始容量大小
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
//自定义初始容量大小
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
//等同于无参构造方法
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
}
}
有参构造 ArrayList(Collection<? extends E> c)
//Constructs a list containing the elements of the specified collection, in the order they are returned by the collection's iterator.
//按照集合迭代器返回元素的顺序构造包含指定集合的元素的列表
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
//每个集合的toarray()的实现方法不一样,所以需要判断一下,如果不是Object[].class类型,那么久需要使用ArrayList中的方法去改造一下。
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
//等同于无参构造方法
this.elementData = EMPTY_ELEMENTDATA;
}
}
add方法的源码分析
boolean add(E)
情况1 无参初始化并添加一个元素
/*
ArrayList arr = new ArrayList(); //这句可以理解为初始化一个空的数组
arr.add(xxx);
*/
//Appends the specified element to the end of this list.
//添加一个特定的元素到list的末尾
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
/*
进入这个函数ensureCapacityInternal(size + 1);
size是数组中数据的个数,因为要添加一个元素,所以size+1
*/
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
/*
进入这个函数calculateCapacity(elementData, minCapacity);
其中elementData还是空的数组,minCapacity=初始size的值+1=1
*/
private static int calculateCapacity(Object[] elementData, int minCapacity) {
/*
注意:若a,b都为数组,则:
a=b ,比较的是地址
a.equals(b) 比较的是地址
Arrays.equals(a, b) 比较的是元素内容
当比较两个字符串的时候,它使用的是String类下的equals()方法,这个方法比较的是对象值。
当比较两个数组的值的时候,需要使用Arrays类中的equals()方法。即Arrays.equals(a, b)
*/
//在构造函数中this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
//所以if语句执行true Math.max(10, 1)=10 返回10
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
/*
进入这个函数ensureCapacityInternal(int minCapacity); 此时minCapacity=10
但注意还没有真正的改变这个elementData的大小
*/
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
// minCapacity=10 elementData.length=0 所以minCapacity - elementData.length > 0
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/*
进入这个函数grow(minCapacity); minCapacity=10 这是数组扩容的核心函数
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length; //oldCapacity=0
int newCapacity = oldCapacity + (oldCapacity >> 1); //newCapacity= 0 + 0 = 0
//newCapacity - minCapacity = -10 < 0执行下面if语句
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity; //此时newCapacity=10
//如果newCapacity超过了最大的容量限制,就调用hugeCapacity,也就是将能给的最大值给 newCapacity
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
//minCapacity is usually close to size, so this is a win:
//新的容量大小已经确定好了,就copy数组,改变容量大小
elementData = Arrays.copyOf(elementData, newCapacity);
}
/*
如果newCapacity超过了最大的容量限制,就调用hugeCapacity
*/
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
//如果minCapacity大于MAX_ARRAY_SIZE,那么就Integer.MAX_VALUE返回,反之将 MAX_ARRAY_SIZE返回
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
/*
最后再回过来执行boolean add(E e)
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
情况2 有参初始化并添加一个元素
/*
ArrayList arr = new ArrayList(6); //这句可以理解为elementData的大小已经是6
arr.add(xxx);
*/
private static int calculateCapacity(Object[] elementData, int minCapacity) {
//执行到这一步的时候 if语句不成立 返回minCapacity=size+1=1
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
// minCapacity - elementData.length = 1 - 6 < 0 所以不会执行grow函数,也就不会扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
情况3 无餐初始化并添加第11个元素时
/*
ArrayList arr = new ArrayList(); //这句可以理解为初始化一个空的数组
arr.add(xxx);
:
:
arr.add(xxx);
arr.add(xxx); 已经添加10个元素,要添加第11个元素时
添加了第10个元素时,执行elementData[size++] = e; 意味着elementData[size] = e,然后size自增等于10
*/
private static int calculateCapacity(Object[] elementData, int minCapacity) {
//执行到这一步的时候 if语句不成立 返回minCapacity=size+1=11
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
// minCapacity - elementData.length = 11 - 10 > 0 所以会执行grow函数,扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length; //oldCapacity=10
//oldCapacity >> 1表示算术右移1位
//打个比方10的二进制是01010算术右移1位,得00101即转为10进制为5
int newCapacity = oldCapacity + (oldCapacity >> 1); //newCapacity= 10 + 5 = 15
//newCapacity - minCapacity = 15 - 11 >0
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//如果newCapacity超过了最大的容量限制,就调用hugeCapacity,也就是将能给的最大值给 newCapacity
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
//minCapacity is usually close to size, so this is a win:
//新的容量大小已经确定好了,就copy数组,改变容量大小
elementData = Arrays.copyOf(elementData, newCapacity);
}
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e; //扩容完之后再执行这行代码
return true;
}
void add(int,E)
public void add(int index, E element) {
//检查index也就是插入的位置是否合理。
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
//将elementData从index开始的元素复制到elementData上,从index + 1开始复制,复制长度为size - index
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
//rangeCheckForAdd(int index)
private void rangeCheckForAdd(int index) {
//插入的位置肯定不能大于size 和小于0
if (index > size || index < 0)
//如果是,就报这个越界异常
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
//void arraycopy
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
remove方法的源码分析
remove(int)
public E remove(int index) {
//检查index的合理性
rangeCheck(index);
modCount++;
E oldValue = elementData(index);//通过索引直接找到该元素
int numMoved = size - index - 1;//计算要移动的位数
if (numMoved > 0)
//使用System.arraycopy移动复制元素
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
remove(Object)
public boolean remove(Object o) {
//显然arrayList可以存储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)方法的内部跟remove(index)的实现几乎一样
fastRemove(index);
return true;
}
}
return false;
}
removeAll(collection c)
public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c);
return batchRemove(c, false);
}
//batchRemove是removeAll的核心方法,用于两处地方,如果complement为false,则用于removeAll;如果为true,则用于 retainAll(),retainAll()是用来检测两个集合是否有交集的。
private boolean batchRemove(Collection<?> c, boolean complement) {
final Object[] elementData = this.elementData;
int r = 0, w = 0;//r用来控制循环,w是记录有多少个交集,可以r,w分别看成两个指针在数组之间移动
boolean modified = false;
try {
for (; r < size; r++)
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];
} finally {
// Preserve behavioral compatibility with AbstractCollection,
// even if c.contains() throws.
//通常情况下,如果程序正常执行,最后r==size,如果r!=size说明contains方法使用过程报异常
if (r != size) {
//r之前的元素都已经完成,将elementData的r指针开始的位置复制到elementData的w指针开始的位置,复制size - r长度
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r; //w指针移动size - r个单位
}
//retainAll():没有一个交集返回true,有交集但不全交也返回true,而两个集合 相等的时候,返回false,所以不能根据返回值来确认两个集合是否有交集
if (w != size) {
// clear to let GC do its work
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}
其他方法
set(int,E)
public E set(int index, E element) {
//检验索引是否合法
rangeCheck(index);
//找出旧值
E oldValue = elementData(index);
//赋新值
elementData[index] = element;
//返回旧值
return oldValue;
}
indexOf(Object)
//从首开始查找数组里面是否存在指定元素
public int indexOf(Object o) {
if (o == null) {
// 遍历数组,找到第一个为空的元素,返回下标
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
// 遍历数组,找到第一个和指定元素相等的元素,返回下标
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
get(int)方法
public E get(int index) {
//检验索引是否合法
rangeCheck(index);
//返回索引对应的元素值
return elementData(index);
}
Hi, welcome to JasperのBlog!