http://www.blogjava.net/EvanLiu/archive/2007/11/12/159884.html 集合继承关系图
Collection是一个超级接口,有很多实现这个接口的类。具体用的话,是用这些实现它的那些类,比如ArrayList等,ArrayList是比较常用的。
Collection 也属于容器,容器的话,一般避免不了“增删改查”这四个操作!
iterator
所有实现Collection接口容器类都有一个iterator方法用以返回一个实现iterator接口对象
iterator对象称迭代器,方便对实现对容器内元素的遍历操作。
set
set集合不忍许加入两个相同得元素,同时比较得时候是通过equals方法来比较。
(==比较的是2个对象的地址,而equals比较的是2个对象的内容)
hashset
hashset是set接口得典型实现,大多说时候使用set集合时都是使用这个实现类,
hashset按hash算法来存储集合中的元素,因此具有很好的存储和查找性能。
hashset具有一下特点:
不能保证元素得排列顺序
hashset不是线程安全的
集合元素可以使用null
存入元素得时候根据hansCode的值决定该对象在hashset中存储的位置(所以不能保证元素得储存位置)。如果equals的值相同,但是hashCode不同,还是可以把它存在不同的位置。
LinkedHashSet
LinkedHashSet是hashSet的子类
LinkedHashSet集合根据元素的hashCode值来决定元素得存储位置,同时使用链表维护元素得次序,这使得元素看起来是以插入的顺序保存的,
LinkedHashSet的插入稍微低于hashset但是迭代访问得set里的全部元素时有很好得性能。
LinkedHashSet不容许集合元素重复。
TreeSet时SortedSet接口的实现类,TreeSet可以确保集合处于排序状态。
treeSet支持两种排序方法,自然排序和定制排序,默认得情况下,TreeSet采用自然排序。
* 如果想把自定义类的对象存入TreeSet进行排序, 那么必须实现Comparable接口
* 在类上implement Comparable
* 重写compareTo()方法
* 在方法内定义比较算法, 根据大小关系, 返回正数负数或零
* 在使用TreeSet存储对象的时候, add()方法内部就会自动调用compareTo()方法进行比较, 根据比较结果使用二叉树形式进行存储
*/
import java.util.Iterator; import java.util.*; public class TreeSetTest { public static void main(String[] args) { Set ts = new TreeSet(); ts.add("abc"); ts.add("xyz"); ts.add("rst"); Iterator it = ts.iterator(); while (it.hasNext()) { System.out.println(it.next()); } } }
输出结果:
abc
rst
xyz
打印结果不是和先前加入的顺序一样,它是按照一个字母的排序法进行排序的。这是因为String 类实现了Comparable接口。
如果我们自己定义的一个类的对象要加入到TreeSet当中,那么这个类必须要实现Comparable接口。
package test.treeset; import java.util.Iterator; import java.util.Set; import java.util.TreeSet; public class test_treeset { @SuppressWarnings("unchecked") public static void main(String[] args) { Set ts = new TreeSet(); ts.add(new Teacher("zhangsan", 1)); ts.add(new Teacher("lisi", 2)); ts.add(new Teacher("wangmazi", 3)); ts.add(new Teacher("wangwu",4)); ts.add(new Teacher("mazi", 3)); Iterator it = ts.iterator(); while (it.hasNext()) { System.out.println(it.next()); } } } class Teacher implements Comparable { int num; String name; Teacher(String name, int num) { this.num = num; this.name = name; } public String toString() { return "学号:" + num + "\t\t姓名:" + name; } //o中存放时的红黑二叉树中的节点,从根节点开始比较 public int compareTo(Object o) { Teacher ss = (Teacher) o; int result = num < ss.num ? 1 : (num == ss.num ? 0 : -1);//降序 //int result = num > ss.num ? 1 : (num == ss.num ? 0 : -1);//升序 if (result == 0) { result = name.compareTo(ss.name); } return result; } }
运行结果:
学号:4 姓名:wangwu
学号:3 姓名:mazi
学号:3 姓名:wangmazi
学号:2 姓名:lisi
学号:1 姓名:zhangsan
List
代表一个元素有序,且可重复得集合,集合中的每个元素都有其对应的顺序索引默认按照元素得添加顺序设置元素得索引。
arrayList和Vector是list接口得两个典型得实现,
通常建议使用arraylist。
arraylist时线程不安全得,而vector时线程安全的
list总结;
http://blog.sina.com.cn/s/blog_71a536990101b4gb.html
一 list接口
1.java.util.ArrayList类实现一个可增长的动态数组,平时用的比较多的就是add()方法,其它方法
请参考API帮助文档。使用该方法向集合内添加对象,并且这些对象是按照一定的顺序排列
的,它内部原理是数组实现的,因此处理数据量较大时,不建议使用。
public class TestArrayList { public static void main(String[] args) { //声明List 并实例化为ArrayList List al = new ArrayList(); //使用add()方法添加元素 al.add("a"); al.add("b"); al.add("c"); al.add("d"); //使用Iterator迭代器遍历出集合的元素并打印 for(Iterator i = al.iterator();i.hasNext(); ){ String str = (String) i.next(); System.out.println(str); } } }
3.java.util.Vector(向量)类 与ArrayList类似的也是实现一个动态的数组,该向量可以随意的增长以存放更多的对象
public class TestArrayList { public static void main(String[] args) { //声明List 并实例化为Vector List al = new Vector(); //使用add()方法添加对象 al.add("a"); al.add("b"); al.add("c"); al.add("d"); //使用Iterator迭代器遍历出集合的对象并打印 for(Iterator i = al.iterator();i.hasNext(); ){ String str = (String) i.next(); System.out.println(str); } } }
3.java.util.LinkedList类实现了链表,可初始化化为空或者已存在的集合,通常使用以下方法
add();向链表末尾添加对象。
addFirst()在链表开头添加对象。
addLast()在链表末尾添加对象。
getFirst()得到链表开头的对象。
getLast()得到链表末尾的对象。
注意该类提供了随机访问列表中的元素的方法,但是底层依然必须遍历去查找随机访问的对象,因此性能依然有限.
public static void main(String[] args) { //声明LinkedList并实例化 LinkedList al = new LinkedList(); //使用add()方法添加元素 al.add("a"); al.add("b"); al.add("c"); al.add("d"); //使用Iterator迭代器遍历出集合的元素并打印 for(Iterator i = al.iterator();i.hasNext(); ){ String str = (String) i.next(); System.out.println(str); } System.out.println("_____"); //向链表头和尾分别添加x和z al.addFirst("z"); al.addLast("x"); //遍历查看添加后的结果 for(Iterator i = al.iterator();i.hasNext(); ){ String str = (String) i.next(); System.out.println(str); } }
4.java.util.Stack类实现了堆栈数据结构,即按照先进后出的原则存放数据。创建时只能为空。
使用push()方法进行添加对象
public static void main(String[] args) { //声明Stack并实例化 Stack al = new Stack(); //使用push()方法添加元素 al.push("a"); al.push("b"); al.push("c"); al.push("d"); al.push("f"); //使用Iterator迭代器遍历出集合的元素并打印 for(Iterator i = al.iterator();i.hasNext(); ){ String str = (String) i.next(); System.out.println(str); } }
Java中HashMap,LinkedHashMap,TreeMap的区别
java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMap Hashtable LinkedHashMap 和TreeMap
Map主要用于存储健值对,根据键得到值,因此不允许键重复(重复了覆盖了),但允许值重复。
Hashmap 是一个最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度,遍历时,取得数据的顺序是完全随机的。HashMap最多只允许一条记录的键为Null;允许多条记录的值为 Null;HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力,或者使用ConcurrentHashMap。
Hashtable与 HashMap类似,它继承自Dictionary类,不同的是:它不允许记录的键或者值为空;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了 Hashtable在写入时会比较慢。
LinkedHashMap保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.也可以在构造时用带参数,按照应用次数排序。在遍历的时候会比HashMap慢,不过有种情况例外,当HashMap容量很大,实际数据较少时,遍历起来可能会比LinkedHashMap慢,因为LinkedHashMap的遍历速度只和实际数据有关,和容量无关,而HashMap的遍历速度和他的容量有关。
TreeMap实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。
一般情况下,我们用的最多的是HashMap,HashMap里面存入的键值对在取出的时候是随机的,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。在Map 中插入、删除和定位元素,HashMap 是最好的选择。
TreeMap取出来的是排序后的键值对。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。
LinkedHashMap 是HashMap的一个子类,如果需要输出的顺序和输入的相同,那么用LinkedHashMap可以实现,它还可以按读取顺序来排列,像连接池中可以应用。
以下代码实例可以看出HashMap,LinkedHashMap,TreeMap的区别:
import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.TreeMap; public class Ceshi{ @SuppressWarnings("unchecked") public static void main(String[] args) { //HashMap System.out.println("------HashMap无序输出------"); HashMap hsMap=new HashMap(); hsMap.put("3", "Value3"); hsMap.put("1", "Value1"); hsMap.put("2", "Value2"); hsMap.put("b", "ValueB"); hsMap.put("a", "ValueA"); Iterator it = hsMap.entrySet().iterator(); while (it.hasNext()) { Map.Entry e = (Map.Entry) it.next(); System.out.println("Key: " + e.getKey() + "--Value: " + e.getValue()); } //TreeMap System.out.println("------TreeMap按Key排序输出------"); TreeMap teMap=new TreeMap(); teMap.put("3", "Value3"); teMap.put("1", "Value1"); teMap.put("2", "Value2"); teMap.put("b", "ValueB"); teMap.put("a", "ValueA"); Iterator tit = teMap.entrySet().iterator(); while (tit.hasNext()) { Map.Entry e = (Map.Entry) tit.next(); System.out.println("Key: " + e.getKey() + "--Value: " + e.getValue()); } //LinkedHashMap System.out.println("--LinkedHashMap根据输入的顺序输出--"); LinkedHashMap lhsMap=new LinkedHashMap(); lhsMap.put("3", "Value3"); lhsMap.put("1", "Value1"); lhsMap.put("2", "Value2"); lhsMap.put("b", "ValueB"); lhsMap.put("a", "ValueA"); Iterator lit = lhsMap.entrySet().iterator(); while (lit.hasNext()) { Map.Entry e = (Map.Entry) lit.next(); System.out.println("Key: " + e.getKey() + "--Value: " + e.getValue()); } } }
执行结果为:
------HashMap无序输出------
Key: 3--Value: Value3
Key: 2--Value: Value2
Key: 1--Value: Value1
Key: b--Value: ValueB
Key: a--Value: ValueA
------TreeMap按Key排序输出------
Key: 1--Value: Value1
Key: 2--Value: Value2
Key: 3--Value: Value3
Key: a--Value: ValueA
Key: b--Value: ValueB
--LinkedHashMap根据输入的顺序输出--
Key: 3--Value: Value3
Key: 1--Value: Value1
Key: 2--Value: Value2
Key: b--Value: ValueB
Key: a--Value: ValueA