JAVA基础之集合框架详解

参考文章:
https://www.cnblogs.com/xiaoxi/p/6089984.html
http://www.importnew.com/16658.html
1.集合框架图 Java的集合类主要由两个接口派生而出:Collection和Map,Collection和Map是Java集合框架的根接口,这两个接口又包含了一些子接口或实现类。 JAVA基础之集合框架详解
文章图片
image.png 2.Collection接口(Collection包含了List和Set两大分支。) 2.1 List接口的实现类(ArrayList,Vector,LinkedList,Stack) (1).ArrayList ArrayList是一个动态数组,它允许任何符合规则的元素插入甚至包括null,每一个ArrayList都有一个初始容量(10),随着容器中的元素不断增加,容器的大小也会随着增加。在每次向容器中增加元素的同时都会进行容量检查,当快溢出时,就会进行扩容操作。所以如果我们明确所插入元素的多少,最好指定一个初始容量值,避免过多的进行扩容操作而浪费时间、效率。
注意: ArrayList擅长于随机访问。同时ArrayList是非同步的。 (2).Vector 与ArrayList相似,但是Vector是同步的。所以说Vector是线程安全的动态数组。它的操作与ArrayList几乎一样。
(3).LinkedList 【JAVA基础之集合框架详解】同样实现List接口的LinkedList与ArrayList不同,ArrayList是一个动态数组,而LinkedList是一个双向链表,
由于实现的方式不同,LinkedList不能随机访问,它所有的操作都是要按照双重链表的需要执行。在列表中索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端)。这样做的好处就是可以通过较低的代价在List中进行插入和删除操作。
与ArrayList一样,LinkedList也是非同步的。如果多个线程同时访问一个List,则必须自己实现访问同步。
注意:创建List时构造一个同步的List:List list = Collections.synchronizedList(new LinkedList(...)); (4).Stack Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop 方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。

private static void testStack() { /*** * 栈是一种只能在一端进行插入或删除操作的线性表 * 特性:先进后出 */ Stack stack=new Stack<>(); //进栈push() stack.push("1"); stack.push("2"); stack.push("3"); stack.push("4"); System.out.println("statck data:"+stack.toString()); // 取栈顶值(不出栈) System.out.println("stack top:"+stack.peek()); //出栈 //stack.pop(); // stack.pop(); //stack.pop(); System.out.println("stack data:"+stack.toString()); System.out.println("stack is empty:"+stack.empty()); int index=stack.search("3"); //计数从顶部开始 System.out.println("stack search index:"+index); System.out.println("stack search result:"+ stack.get(0)); List list=new ArrayList<>(); list.add("1"); list.add("2"); list.add("3"); list.add("4"); System.out.println("list is empty:"+list.get(3)); Iterator iterator=list.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } }

2.2 Set接口的实现类(HashSet,LinkedHashSet,TreeSet) (1)HashSet HashSet 是一个没有重复元素的集合。它是由HashMap实现的,不保证元素的顺序(这里所说的没有顺序是指:元素插入的顺序与输出的顺序不一致),而且HashSet允许使用null 元素。HashSet是非同步的,如果多个线程同时访问一个哈希set,而其中至少一个线程修改了该set,那么它必须保持外部同步。 HashSet按Hash算法来存储集合的元素,因此具有很好的存取和查找性能。
注意:HashSet是由HashMap实现,不保证元素的插入顺序,可以存放null值,仅仅能够存入一个null值。
private static void testHashSet() { /**** * 元素不重复 */ Set hashSet=new HashSet<>(); hashSet.add("javabbb"); hashSet.add("java01"); hashSet.add("java01"); hashSet.add("java03"); hashSet.add("java02"); SethashSet1=new HashSet<>(); hashSet1.add("java05"); hashSet1.add("java04"); hashSet1.add("javaaaa"); hashSet.add(null); //可以插入null hashSet.add(null); hashSet.addAll(hashSet1); boolean isEmpty=hashSet.isEmpty(); //遍历 Iterator iterator= hashSet.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } }

输出结果:

JAVA基础之集合框架详解
文章图片
image.png (2)LinkedHashSet LinkedHashSet继承自HashSet,其底层是基于LinkedHashMap来实现的,有序,非同步。LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。
注意:LinkedHashSet底层是基于LinkedHashMap来实现
private static void testLinkedHashSet() { /**** * 因为是链表,所以有序输出 * 元素不重复 */ Set linkedHashSet=new LinkedHashSet<>(); linkedHashSet.add("java01"); linkedHashSet.add("java01"); linkedHashSet.add("java02"); linkedHashSet.add("java03"); Set linkedHashSet1=new LinkedHashSet<>(); linkedHashSet1.add("java04"); linkedHashSet1.add("java05"); linkedHashSet1.add(null); linkedHashSet1.add(null); linkedHashSet.addAll(linkedHashSet1); //遍历 Iterator iterator= linkedHashSet.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); }}

输出结果:

JAVA基础之集合框架详解
文章图片
image.png (3)TreeSet TreeSet是一个有序集合,其底层是基于TreeMap实现的,非线程安全。TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序和定制排序,其中自然排序为默认的排序方式。当我们构造TreeSet时,若使用不带参数的构造函数,则TreeSet的使用自然比较器;若用户需要使用自定义的比较器,则需要使用带比较器的参数。
注意:TreeSet底层是基于TreeMap来实现,Set集合都是非线程安全的
private static void testIntegerSort() { System.out.println("Integer对象自然排序:"); TreeSet treeSetFirst = new TreeSet<>(); treeSetFirst.add(2); treeSetFirst.add(1); treeSetFirst.add(4); treeSetFirst.add(3); treeSetFirst.add(5); Iterator iterator=treeSetFirst.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } } private static void testDictionarySort() { System.out.println("Dictionary对象自然排序:"); TreeSet treeSetFirst = new TreeSet<>(); treeSetFirst.add("Baidu"); treeSetFirst.add("Tecent"); treeSetFirst.add("Ali"); treeSetFirst.add("WanDa"); treeSetFirst.add("HengDa"); treeSetFirst.add("12"); treeSetFirst.add("23a#"); treeSetFirst.add("#"); Iterator iterator=treeSetFirst.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } }private static void testCompatorSort() { Set treeSet=new TreeSet<>(); treeSet.add(new Student("tecent",2)); treeSet.add(new Student("JD",1)); treeSet.add(new Student("wanda",3)); treeSet.add(new Student("baidu",2)); treeSet.add(new Student("ali",2)); treeSet.add(new Student("tecent",2)); //重复的元素被剔除了 System.out.println(treeSet); Iterator itTSet = treeSet.iterator(); //遍历输出 while(itTSet.hasNext()){ System.out.print(itTSet.next() + "\n"); } }private static void testSubHeadTailSet() { TreeSet nums = new TreeSet(); nums.add(5); nums.add(2); nums.add(3); nums.add(8); nums.add(8); //输出集合元素,可以看到集合元素已经处于排序状态,输出【2,3,5,8】 System.out.println(nums); //输出排序后集合里的第一个元素2 System.out.println(nums.first()); //输出排序后集合里最后一个元素 System.out.println(nums.last()); //输出小于4的集合,不包含4,输出【2,3】 System.out.println(nums.headSet(4)); //输出大于5的集合,如果set集合中有5,子集中还应该有5,输出【5,8】 System.out.println(nums.tailSet(5)); //输出大于2,小于5的子集,包括2,不包括5,输出集合【2,3】 System.out.println(nums.subSet(2, 5)); } public static class Student implements Comparable { int num; String name; public Student( String name,int num) { this.num = num; this.name = name; }@Override public String toString() { return "StudentNo:" + num + " ,StudentName:" + name; }public int getNum() { return num; }public void setNum(int num) { this.num = num; }public String getName() { return name; }public void setName(String name) { this.name = name; }@Override public int compareTo(Object o) { Student student= (Student) o; if(num

输出结果:

JAVA基础之集合框架详解
文章图片
image.png 3.Map接口 Map与List、Set接口不同,它是由一系列键值对组成的集合,提供了key到Value的映射。同时它也没有继承Collection。在Map中它保证了key与value之间的一一对应关系。也就是说一个key对应一个value,所以它不能存在相同的key值,当然value值可以相同。
(1).HashMap HashMap可以通过调用Collections的静态方法Collections.synchronizedMap(Map map)进行同步,最多只允许一条记录的键为Null,不支持线程的同步,无序
private static void testHashMap() { /*** * hashmap的key和value都可以为null */ Map map = new HashMap<>(); for (int i = 0; i <= 3; i++) { map.put("key" + i, "value" + i); } map.put(null,"value4"); map.put(null,"value5"); map.put("key6",null); map.put("key7",null); map.get("key" + 5); for (String key : map.keySet()) { System.out.println(map.get(key)); } }

输出结果:

JAVA基础之集合框架详解
文章图片
image.png 输出结果:

JAVA基础之集合框架详解
文章图片
image.png (2).LinkedHashMap LinkedHashMap是HashMap的一个子类,它保留插入的顺序,如果需要输出的顺序和输入时的相同,那么就选用LinkedHashMap。允许使用null值和null键
private static void testLinkHashMap() { //linkedhashmapextends hashmap 比hashmap功能更强大 Map map = new LinkedHashMap<>(); for (int i = 0; i <= 3; i++) { map.put("key" + i, "value" + i); } map.put(null,"value4"); map.put(null,"value5"); map.put("key6",null); map.put("key7",null); map.get("key" + 5); for (String key : map.keySet()) { System.out.println(map.get(key)); } }

输出结果:

JAVA基础之集合框架详解
文章图片
image.png (2).Hashtable 线程同步,同时key,value都不可以为null,无序的
private static void testHashtable() { /*** * 线程同步的,同时key,value都不可以为null,无序的 */ Hashtable hashtable = new Hashtable(); hashtable.put("baidu","101"); hashtable.put("ali","102"); hashtable.put("tencent","103"); hashtable.put("wanda","105"); hashtable.put("pingan","107"); hashtable.put("hengda","106"); hashtable.put("transsion","104"); // hashtable.put(null,"2"); //java.lang.NullPointerException //hashtable.put("wanke",null); //java.lang.NullPointerException for(String key:hashtable.keySet()){ System.out.println(key+"="+hashtable.get(key)); } }

(4).ConCurrentHashMap ConcurrentHashMap和HashTable都是线程安全的,无序的,key和value都不能为null,性能上要比Hashtable要强,是一个加强版本的Hashtable。
private static void testConcurrentHashMap() { /*** * ConcurrentHashMap和HashTable都是线程安全的,可以在多线程中进行, * key和value都不能为null,性能上要比Hashtable要强 * 线程同步的,同时key,value都不可以为null */ ConcurrentHashMap concurrentHashMap = new ConcurrentHashMap(); concurrentHashMap.put("baidu","101"); concurrentHashMap.put("ali","102"); concurrentHashMap.put("tencent","103"); concurrentHashMap.put("wanda","105"); concurrentHashMap.put("pingan","107"); concurrentHashMap.put("hengda","106"); concurrentHashMap.put("transsion","104"); // concurrentHashMap.put(null,"2"); //java.lang.NullPointerException // concurrentHashMap.put("wanke",null); //java.lang.NullPointerException for(String key:concurrentHashMap.keySet()){ System.out.println(key+"="+concurrentHashMap.get(key)); } }

输出结果:

JAVA基础之集合框架详解
文章图片
image.png (5).TreeMap TreeMap 是一个有序的key-value集合,非同步,基于红黑树(Red-Black tree)实现,每一个key-value节点作为红黑树的一个节点。TreeMap存储时会进行排序的,会根据key来对key-value键值对进行排序,其中排序方式也是分为两种,一种是自然排序,一种是定制排序,具体取决于使用的构造方法。
注意:key不能为null,value可以为null
//自然排序顺序: public static void naturalSort(){ //第一种情况:Integer对象 System.out.println("Integer对象自然排序:"); TreeMap treeMapFirst = new TreeMap(); treeMapFirst.put(1,"jiaboyan"); treeMapFirst.put(6,"jiaboyan"); treeMapFirst.put(3,"jiaboyan"); treeMapFirst.put(10,"jiaboyan"); treeMapFirst.put(7,"jiaboyan"); treeMapFirst.put(13,"jiaboyan"); //treeMapFirst.put(null,"jiaboyan"); java.lang.NullPointerException treeMapFirst.put(14,null); //可以运行 System.out.println(treeMapFirst.toString()); //第二种情况:SortedTest对象 System.out.println("SortedTest对象排序一:"); TreeMap treeMapSecond = new TreeMap(); treeMapSecond.put(new SortedTest(10),"jiaboyan"); treeMapSecond.put(new SortedTest(1),"jiaboyan"); treeMapSecond.put(new SortedTest(13),"jiaboyan"); treeMapSecond.put(new SortedTest(4),"jiaboyan"); treeMapSecond.put(new SortedTest(0),"jiaboyan"); treeMapSecond.put(new SortedTest(9),"jiaboyan"); System.out.println(treeMapSecond.toString()); //默认是根据key的自然排序来组织(比如integer的大小,String的字典排序) System.out.println("integer和字典对象排序二:"); TreeMap treeMapThree = new TreeMap(); treeMapThree.put("2key1",new SortedTest(10)); treeMapThree.put("1key2",new SortedTest(1)); treeMapThree.put("bey3",new SortedTest(13)); treeMapThree.put("key6",new SortedTest(4)); treeMapThree.put("key5",new SortedTest(0)); treeMapThree.put("key4",new SortedTest(9)); System.out.println(treeMapThree.toString()); }public static class SortedTest implements Comparable { private int age; public SortedTest(int age){ this.age = age; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }@Override public String toString() { return "age:"+age; }//自定义对象,实现compareTo(T o)方法: public int compareTo(SortedTest sortedTest) { int num = this.age - sortedTest.getAge(); //为0时候,两者相同: if(num==0){ return 0; //大于0时,传入的参数小: }else if(num>0){ return 1; //小于0时,传入的参数大: }else{ return -1; } } }

输出结果:

JAVA基础之集合框架详解
文章图片
image.png

    推荐阅读