修炼完这一篇秘籍,你就可以成为四段斗之气战士了,天赋出色者甚至可以越阶战斗,成为百里挑一的斗者,踏上漫漫强者路,拳打北山幼儿园,脚踢南海敬老院。
该系列文章上一篇: 三段斗之气–Java集合框架概述.
该系列文章下一篇: 五段斗之气–Collection的子接口:List接口.
Collection接口是List、Set和Queue接口的父接口,该接口里定义的方法既可用于操作List集合,也可用于操作Set和Queue集合。JDK没有提供Collection接口的任何直接实现,而是提供了更具体地子接口。在Java5之前,Java集合把所有对象都当成Object类型处理,从JDK5.0增加了泛型以后,Java集合就可以记住容器中对象的数据类型了。通过一棵接口继承数可以很直观清晰的了解到我们需要关注的内容。
初看上去光实现类就有六个,其实搞清楚它们各自之间的性能特点,行为区别之后,就不会再觉得难以记忆了,况且在日常开发中最常用的往往就是那特定几个类的特定方法,并没有多么复杂。弄清楚一些关键问题也可以帮助自己记忆,比如Vector、ArrayList、LinkedList的异同点是什么?Set和List的区别是什么?这些问题在后面内容中都会详细的进行分析。
Collection接口是一种集合的行为规范,它里面定义了一些接口方法,凡是继承或者实现了该接口的类和接口,都必须具备和它一样的行为规范,因此可以先研究一下Collection接口中定义的方法,看它具备哪些功能,换言之也就是先对List接口和Set接口有哪些共有的方法进行研究,后面再一层层具体看每个子接口下面每个具体类有哪些独有的功能。
常用方法 | 方法声明 |
---|---|
添加 | add(Object obj) add(Collection coll) |
存储个数 | int size():注意获取的不是集合的总大小,而是存储的有效元素个数 |
清空集合 | void clear() |
是否为空 | boolean isEmpty() |
是否包含 | boolean contains(Object obj):是通过元素的equals方法来判断是否是同一个对象 boolean containsAll(Collection c):也是将两个集合里面的元素挨个用equals方法比较。 |
删除 | boolean remove(Object obj):通过元素的equals方法判断是否存在该元素,只会删除找到的第一个元素 boolean removeAll(Collection coll):取当前两个集合的差集 |
取交集 | boolean retainAll(Collection c):把交集的结果存在当前集合中,不影响c |
是否相等 | boolean equals(Object obj) |
获取哈希值 | hashCode() |
遍历 | iterator:返回迭代器对象,用于集合遍历 |
这些方法都是在日常开发中比较常用的,因此有必要对每个方法进行测试,这里选择使用ArrayList作为具体的实现类来对Collection接口中的方法进行测试,代码编译环境是JDK1.8。
package com.learnjiawa.jihe;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/**
* Collection接口中声明的方法的测试
*
* 结论:
* 向Collection接口的实现类的对象中添加数据obj时,要求obj所在类要重写equals().
*
* @author shkstart
* @create 2019 上午 10:04
*/
public class CollectionTest {
@Test
public void test1(){
//创建一个Arraylist类,用Collection规范它的行为
Collection coll = new ArrayList();
// ArrayList coll1 = new ArrayList(); //coll和coll1的行为有区别
coll.add(123);
coll.add(456);
Person p = new Person("Jerry",20);
coll.add(p);
coll.add(new Person("Jerry",20));
coll.add(new String("Tom"));
coll.add(false);
//1.contains(Object obj):判断当前集合中是否包含obj
//我们在判断时会调用obj对象所在类的equals()。
// boolean contains = coll.contains(123);
// System.out.println(contains);
// System.out.println(coll.contains(new String("Tom")));
// System.out.println(coll.contains(p));//true
System.out.println(coll.contains(new Person("Jerry",20)));//false -->true
/*
* 如果不重写Person类中的equals方法,上面会返回false,因为默认的equals方法里面是用“==”
* 比较的对象地址,而重新new的person对象很明显地址不相同,所以返回false
* 如果判断是否包含p,就算不重写equals方法也会返回true,因为p引用本来就指向的同一个地址
* */
//2.containsAll(Collection coll1):判断形参coll1中的所有元素是否都存在于当前集合中。
Collection coll1 = Arrays.asList(123,4567);
System.out.println(coll.containsAll(coll1));
}
@Test
public void test2(){
//3.remove(Object obj):从当前集合中移除obj元素。
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Person("Jerry",20));
coll.add(new String("Tom"));
coll.add(false);
coll.remove(1234);
System.out.println(coll);
coll.remove(new Person("Jerry",20));
System.out.println(coll);
//4. removeAll(Collection coll1):差集:从当前集合中移除coll1中所有的元素。
Collection coll1 = Arrays.asList(123,456);
coll.removeAll(coll1);
System.out.println(coll);
}
@Test
public void test3(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Person("Jerry",20));
coll.add(new String("Tom"));
coll.add(false);
//5.retainAll(Collection coll1):交集:获取当前集合和coll1集合的交集,并返回给当前集合
// Collection coll1 = Arrays.asList(123,456,789);
// coll.retainAll(coll1);
// System.out.println(coll);
//6.equals(Object obj):要想返回true,需要当前集合和形参集合的元素都相同。
Collection coll1 = new ArrayList();
coll1.add(456);
coll1.add(123);
coll1.add(new Person("Jerry",20));
coll1.add(new String("Tom"));
coll1.add(false);
System.out.println(coll.equals(coll1));
}
@Test
public void test4(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Person("Jerry",20));
coll.add(new String("Tom"));
coll.add(false);
//7.hashCode():返回当前对象的哈希值
System.out.println(coll.hashCode());
//8.集合 --->数组:toArray()
Object[] arr = coll.toArray();
for(int i = 0;i < arr.length;i++){
System.out.println(arr[i]);
}
//拓展:数组 --->集合:调用Arrays类的静态方法asList()
List<String> list = Arrays.asList(new String[]{"AA", "BB", "CC"});
System.out.println(list);
List arr1 = Arrays.asList(new int[]{123, 456});
System.out.println(arr1.size());//1
List arr2 = Arrays.asList(new Integer[]{123, 456});
System.out.println(arr2.size());//2
//9.iterator():返回Iterator接口的实例,用于遍历集合元素。放在IteratorTest.java中测试
}
}
package com.learnjiawa.jihe;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* 集合元素的遍历操作,使用迭代器Iterator接口
* 1.内部的方法:hasNext() 和 next()
* 2.集合对象每次调用iterator()方法都得到一个全新的迭代器对象,
* 默认游标都在集合的第一个元素之前。
* 3.内部定义了remove(),可以在遍历的时候,删除集合中的元素。此方法不同于集合直接调用remove()
*/
public class IteratorTest {
@Test
public void test1(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Person("Jerry",20));
coll.add(new String("Tom"));
coll.add(false);
Iterator iterator = coll.iterator();
//方式一:
// System.out.println(iterator.next());
// System.out.println(iterator.next());
// System.out.println(iterator.next());
// System.out.println(iterator.next());
// System.out.println(iterator.next());
// //报异常:NoSuchElementException
// System.out.println(iterator.next());
//方式二:不推荐
// for(int i = 0;i < coll.size();i++){
// System.out.println(iterator.next());
// }
//方式三:推荐
hasNext():判断是否还有下一个元素
while(iterator.hasNext()){
//next():①指针下移 ②将下移以后集合位置上的元素返回
System.out.println(iterator.next());
}
}
@Test
public void test2(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Person("Jerry",20));
coll.add(new String("Tom"));
coll.add(false);
//错误方式一:跳着输出并且报异常
// Iterator iterator = coll.iterator();
// while((iterator.next()) != null){
// System.out.println(iterator.next());
// }
//错误方式二:
//集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。
while (coll.iterator().hasNext()){
System.out.println(coll.iterator().next());
}
}
//测试Iterator中的remove()
//如果还未调用next()或在上一次调用 next 方法之后已经调用了 remove 方法,
// 再调用remove都会报IllegalStateException。
@Test
public void test3(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Person("Jerry",20));
coll.add(new String("Tom"));
coll.add(false);
//删除集合中"Tom"
Iterator iterator = coll.iterator();
while (iterator.hasNext()){
// iterator.remove();
Object obj = iterator.next();
if("Tom".equals(obj)){
iterator.remove();
// iterator.remove();
}
}
//遍历集合
iterator = coll.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
注意:
除了使用迭代器遍历集合外,还可以使用增强for来遍历集合,增强for的优点是不需要获取所遍历集合或着数组的长度,不需要使用索引访问元素,更加简洁。
去看该系列文章下一篇: 五段斗之气–Collection的子接口:List接口.
[1]Bruce Eckel.Java编程思想(第4版)[M].机械工业出版社,2008:459-524.
对我的文章感兴趣,持续更新中…