collection中定义的方法:
上述类图中,实线边框的是实现类,比如ArrayList,LinkedList,HashMap等,折线边框的是抽象类,比如AbstractCollection,AbstractList,AbstractMap等,而点线边框的是接口,比如Collection,Iterator,List等。
上述的所有集合类,都实现了Iterator(迭代器)接口,这是一个用于遍历集合元素的接口,主要包含hashNext(),next(),remove()三种方法。它的一个子接口LinkedIterator在它的基础上又添加了三种方法,分别是add(),previous(),hasPrevious()。也就是说如果是先Iterator接口,那么在遍历集合中元素的时候,只能往后遍历,被遍历后的元素不会在遍历到,通常无序集合实现的都是这个接口,比如HashSet,HashMap;而那些元素有序的集合,实现的一般都是LinkedIterator接口,实现这个接口的集合可以双向遍历,既可以通过next()访问下一个元素,又可以通过previous()访问前一个元素,比如ArrayList。
迭代器tips:迭代器的作用就是遍历,
实例:
private static void forEach(Iterable iterable){
Iterator iterator = iterable.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
迭代器还有增强式for循环的功能:
private static void forEach(Iterable iterable){
for(Object o:iterable){
System.out.println(o);
}
}
以上两种函数都可以接收Collection 对象。
还有一个特点就是抽象类的使用。如果要自己实现一个集合类,去实现那些抽象的接口会非常麻烦,工作量很大。这个时候就可以使用抽象类,这些抽象类中给我们提供了许多现成的实现,我们只需要根据自己的需求重写一些方法或者添加一些方法就可以实现自己需要的集合类,工作流昂大大降低。
(1)Set:
HashSet:哈希表是通过使用称为散列法的机制来存储信息的,元素并没有以某种特定顺序来存放;可以放null;当向HashSet结合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在HashSet中存储位置。
注意,如果要把一个对象放入HashSet中,重写该对象对应类的equals方法,也应该重写其hashCode()方法。其规则是如果两个对 象通过equals方法比较返回true时,其hashCode也应该相同。另外,对象中用作equals比较标准的属性,都应该用来计算 hashCode的值。所以课本上的一个set实例中,重载了加入对象的hashcode和equals方法。
LinkedHashSet:以元素插入的顺序来维护集合的链接表,允许以插入的顺序在集合中迭代;可以放null;如果希望按照元素插入集合的顺序进行提取元素,用LinkedHashSet,它的元素按添加的顺序存储
如果没有上述需求,应该用HashSet,它的效率比LinkedHashSet高
TreeSet:提供一个使用树结构存储Set接口的实现,对象以升序顺序存储,访问和遍历的时间很快。放null会有异常
相应实例:
<span style="color:#444444;">import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.TreeSet;
public class QuN{
public static void main(String[] strs){
HashSet<String> hs = new HashSet<String>();
hs.add("B");
hs.add("A");
hs.add("D");
hs.add("E");
hs.add("C");
hs.add("F");
System.out.println("HashSet 顺序:\n"+hs);
LinkedHashSet<String> lhs = new LinkedHashSet<String>();
lhs.add("B");
lhs.add("A");
lhs.add("D");
lhs.add("E");
lhs.add("C");
lhs.add("F");
System.out.println("LinkedHashSet 顺序:\n"+lhs);
TreeSet<String> ts = new TreeSet<String>();
ts.add("B");
ts.add("A");
ts.add("D");
ts.add("E");
ts.add("C");
ts.add("F");
System.out.println("TreeSet 顺序:\n"+ts);</span><span style="color:#ff0000;">//Set中的toString方法还是很人性的。 </span><span style="color:#444444;">
}
}</span>
(2)list
一般大家都知道ArrayList和LinkedList的大致区别:
1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。从头开始。
3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class QuN{
public static void main(String[] strs){
List<String> arrList = new ArrayList<String>();
arrList.add("1");
arrList.add("2");
arrList.add("3");
arrList.add("4");
arrList.add("5");
Iterator<String> iterable =arrList.iterator();//必须是Iterator
for (String string : arrList) {
System.out.println(string);
}
}
}
Map:
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,
主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。
HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步(Collections.synchronizedMap)。
常用操作:
import java.util.Hashtable;
public class Main {
public static void main(String[] args) {
Hashtable<String, Integer> numbers = new Hashtable<String, Integer>();
numbers.put("one", 1);
numbers.put("two", 2);
numbers.put("three", 3);
numbers.put("four", 4);
numbers.put("five", 5);
Integer n = numbers.get("two");
Integer nn = numbers.get("six");
if(n != null)
System.out.println(n);
System.out.println(nn);
}
}