黑马程序员—java基础—集合框架

来源:互联网 发布:吉林大学网络教育中心 编辑:程序博客网 时间:2024/05/16 14:51

                                                                     ------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

 

 

集合框架

 

说到集合框架,脑袋里便想到了两个分支,单列集合和双列集合,先上一个整体的结构图片吧(本来应该昨晚发布,停电,今天补充发布)

 

集合的概念:

集合的概念:
 1.数组的弊端:
 1).长度是固定的,后期不能改变;
 2).数组一旦定以后,其类型就固定了,只能存储此类型数据;
 2.Java为我们提供了一些类,这些叫:集合类。这些集合类功能类似于"数组",
 为程序员做"容器"用的。
 3.集合的好处:
 1).我们程序员使用集合时,可以不用关心"长度"信息,我们只需要往里面存东西,或者从内部删除元素

package cn.itcast.demo03_集合的顶层接口_Collection接口中的功能;import java.util.ArrayList;import java.util.Collection;/* * java.util.Collection(接口):它是List和Set的顶层接口; *  * 常用方法: * 说明:下列方法中,看到E类型,把它当做:Object * boolean add(Object e):向集合中添加一个元素boolean remove(Object o):从集合中移除一个元素void clear():清空集合boolean contains(Object o):判断集合中是否包含参数对象boolean isEmpty():判断集合是否为空int size():获取集合内元素的数量 */public class Demo {public static void main(String[] args) {Collection list = new ArrayList();//1.有序的;2.存储重复元素;//Collection list = new HashSet();//1.无序的;2.不存储重复元素;//1.boolean add(Object e):向集合中添加元素:System.out.println(list.add("刘德华"));System.out.println(list.add("周润发"));System.out.println(list.add("谢霆锋"));System.out.println(list.add("黄晓明"));System.out.println(list.add("吴彦祖"));System.out.println(list.add("吴彦祖"));//添加成功//打印集合System.out.println(list);//移除掉"谢霆锋"System.out.println("移除\"谢霆锋\":" + list.remove("谢霆锋"));System.out.println("移除\"高圆圆\":" + list.remove("高圆圆"));System.out.println("移除后,打印集合:" + list);//清空集合/*list.clear();System.out.println("清空集合后,打印集合:" + list);*///判断张学友是否在集合中System.out.println("判断\"张学友\"是否在集合中:" + list.contains("张学友"));System.out.println("判断\"黄晓明\"是否在集合中:" + list.contains("黄晓明"));System.out.println("判断集合是否为空:" + list.isEmpty());//获取元素的数量System.out.println("集合中元素的数量:" + list.size());}}


Collection中的批量的方法:
 boolean addAll(Collection c):将参数集合加入到当前集合中;
 boolean removeAll(Collection c):移除此 collection 中那些也包含在指定 collection 中的所有元素
 boolean containsAll(Collection c):如果此 collection 包含指定 collection 中的所有元素,则返回 true。
 boolean retainAll(Collection c):移除此 collection 中未包含在指定 collection 中的所有元素。都不常用,不做示例

迭代器遍历集合的方法:

package cn.itcast.demo05_集合的顶层接口_Collection接口_遍历的方法;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;/* * Collection中的遍历的方法: *  * 1.Object[] toArray(): * 2.Iterator iterator():迭代器 *  java.util.Iterator(接口): *  boolean hasNext() :  如果仍有元素可以迭代,则返回 true。  *  Object next() :返回迭代的下一个元素  */public class Demo {public static void main(String[] args) {Collection list = new ArrayList();list.add("张三");list.add("李四");list.add("王五");list.add("周六");list.add(10);// 自动装箱int-->Integerlist.add(3.14);// 自动装箱double-->Double// 3.获取Object[]数组/* * Object[] objArray = list.toArray();  * for(int i = 0;i < objArray.length; i++){  * System.out.println(objArray[i]); * } */// 遍历方式二:Iterator it = list.iterator();while (it.hasNext()) {System.out.println(it.next());}}}

LIst集合特有的功能:

package cn.itcast.demo10_List的特有功能;import java.util.ArrayList;import java.util.List;/* * List的特有功能: *  * Collection(接口): * |--List(接口): * 特有功能: * void add(int index,Object element):将element添加到index位置,原index位置上的元素,及后续元素全部后移;Object remove(int index):移除index位置上的元素;Object get(int index):获取index位置上的元素;Object set(int index,Object element):将index位置上的元素替换为参数的element元素遍历的方法:1.ListIterator listIterator():2.结合Collection的size(),和本接口的get(int index)方法,可以使用for循环遍历; * |--Set(接口): */public class Demo {public static void main(String[] args) {//1.实例化一个ListList list = new ArrayList();//2.填充集合list.add("aaa");//Collectionlist.add("bbb");//Collectionlist.add("ccc");//Collection//在bbb的后面添加一个ffflist.add(2,"fff");System.out.println(list);//移除元素//移除ffflist.remove(2);System.out.println("移除到fff后:" + list);//获取ccc元素System.out.println("获取ccc:" + list.get(2));//将aaa替换为xxxSystem.out.println("替换操作的返回值:" + list.set(0, "xxx"));System.out.println("将aaa替换为xxx后:" + list);}}

学习一个异常:并发修改异常

package cn.itcast.demo12_List迭代器的并发修改异常;import java.util.ArrayList;import java.util.List;import java.util.ListIterator;/* * 并发修改异常: *  * 1.产生原因:通常是当我们使用"迭代器"遍历集合时,通过"集合对象"去修改集合中的元素, *          这时,就会产生并发修改异常; * 2.解决方式: * 通过迭代器遍历,就通过迭代器去修改; */public class Demo {public static void main(String[] args) {List list = new ArrayList();list.add("孙悟空");list.add("猪八戒");list.add("沙师弟");list.add("唐三藏");ListIterator it = list.listIterator();while(it.hasNext()){String str = (String)it.next();if(str.equals("唐三藏")){//向集合中添加一个元素:白龙马//list.add("白龙马");//ConcurrentModificationExceptionit.add("白龙马");}}System.out.println(list);}}

list的三个子类的特点:
Collection(接口):单列集合
  |--List(接口):1.有序;2.可以存储重复值;
  |--ArrayList(类):数组实现;线程不安全的(不同步的),效率高;
  |--Vector(类):数组实现;线程安全的(同步的),效率低;
  |--LinkedList(类):链表实现;线程不安全的(不同步的),效率高;
  |--Set(接口):1.无序的;2.不能存储重复值;
 Map(接口):双列集合

Vector集合的特有功能:

package cn.itcast.demo04_Vector的特有功能;import java.util.Vector;/* * Collection(接口): * |--List(接口): * |--ArrayList(类):(无特有成员) * |--Vector(类): * 特有成员: * public void addElement(Object obj):将元素obj添加到集合;public Object elementAt(int index):获取index位置上的元素; * |--Set(接口): */public class Demo {public static void main(String[] args) {//1.实例化一个VectorVector vec = new Vector();//2.填充集合vec.add("aaa");vec.addElement("bbb");vec.addElement("ccc");vec.add("ddd");System.out.println("获取索引为1的元素:" + vec.elementAt(1));//打印System.out.println(vec);}}

LinkedList的特有功能:

import java.util.LinkedList;/* *  * Collection(接口): * |--List(接口): * |--ArrayList(类):(无特有成员) * |--Vector(类): * 特有成员: * public void addElement(Object obj):将元素obj添加到集合;public Object elementAt(int index):获取index位置上的元素;|--LinkedList(类):特有成员:public void addFirst(E e)及addLast(E e)public E getFirst()及getLast()public E removeFirst()及public E removeLast() * |--Set(接口): */public class Demo {public static void main(String[] args) {//1.实例化一个LinkedListLinkedList list = new LinkedList();//2.填充集合//普通的链表/*list.add("aaa");list.add("bbb");list.add("ccc");*///压栈list.addFirst("aaa");list.addFirst("bbb");list.addFirst("ccc");System.out.println("getFirst()获取第一个元素:" + list.getFirst());System.out.println("移除第一个元素:" + list.removeFirst());//打印System.out.println(list);}}

泛型的简介:

import java.util.ArrayList;import java.util.List;/* * 泛型概述和基本使用 *  * 1.对于某些类来说(尤其是集合类),我们很可能期望在这个类中只存储某种特定的类型; * 2.比如:集合类 * 1).本身是可以存储任何的引用类型的元素;这种功能看似非常的强大, *         但取出时,反而为我们带来了一些麻烦; *      2).起始我们在开发中,经常需要在一个集合中只存储一种类型的数据,这样也能避免 *         取出时进行强制转换时产生异常; *      3).这时,Java中提供了一种机制,可以让我在定义集合时,就指定在这个集合中存储 *         某种类型的数据,那么在后续代码中,当我们调用集合的add()方法时,就只能向集合 *         中添加这种类型的数据,否则就会编译异常;这种机制:泛型 *         List<String> list = new ArrayList<String>();//JDK7以前 *         或 *         List<String> list = new ArrarList<>();//JDK7版本之后(常用) *         或 *         List<String> list = nwe ArrayList(); *      4).泛型的其它说明: *      1>.泛型不只可以用在集合类中,类库中有很多其它的一些普通类,也支持泛型; *      2>.泛型,只存在于"编译期",一旦编译成class之后,就将泛型信息丢弃; */public class Demo {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("aaa");list.add("bbb");list.add("ccc");/*list.add(10);list.add(3.14);*///遍历for(int i = 0;i < list.size() ; i++){//如果这里需要向下转型/*Object obj = list.get(i);if(obj instanceof String){String str = (String)obj;System.out.println(str);}if(obj instanceof Integer){Integer intObj = (Integer)obj;System.out.println(intObj);}if(obj instanceof Double){Double dObj = (Double)obj;System.out.println(dObj);}*///使用泛型之后String str = list.get(i);System.out.println(str);}}}


增强for的概述:

 * 1.增强for(也叫:foreach循环)可以很简便的语法遍历:数组、集合
 * 2.例如遍历数组:编译后,被编译成"普通for循环"

遍历集合:编译后,被编译为"迭代器的方式"

3.增强for特点:
  1).在使用增强for时,没有使用"循环变量";
  2).所以,如果在循环过程中需要使用循环变量,那么还得使用普通for循环;
          如果不需要循环变量,只是简单的从头遍历到结尾,那么可以考虑使用"增强for";

简单介绍一下Arrays类中的一个方法:public static <T> List<T> asList(T... a):将数组转换为集合

途径用户界面MVC分层模式:由于代码量太多,就不上代码了,简单说一说MVC模式之我的理解。MVC模式就是将代码分层实现,视图层,控制层,持久层,模型层。以后修改代码方便,修改某一个层的代码不会影响其他层的代码。便于维护

下面开始了set集合的总结:

import java.util.Collection;import java.util.HashSet;/* * Set集合概述: *  * Collection(接口):单列集合 * |--List(接口):1.有序的;2.可以存储重复值; * |--ArrayList(类):数组实现:线程不安全(不同步),效率高; * |--Vector(类):数组实现:线程安全的(同步),效率低; * |--LinkedList(类):链表实现:线程不安全的(不同步),效率高; * |--Set(接口):1.无序的;2.不能存储重复值; * |--HashSet(类): * |--LinkedHashSet(类): * |--TreeSet(类): * Map(接口):双列集合 */public class Demo {public static void main(String[] args) {//1.实例化一个Set对象Collection<String> set = new HashSet<>();//2.填充元素set.add("aaa");set.add("bbb");set.add("ccc");set.add("ddd");//存储重复元素String s1 = new String("ccc");String s2 = new String("ddd");set.add(s1);//添加失败set.add(s2);//添加失败set.add("eee");//3.遍历//1.toArray()//2.iterator();//3.增强for;for(String s : set){System.out.println(s);//取出时,跟存入的顺序不同;}}}

linkedHashSet 集合:

import java.util.LinkedHashSet;/* * Collection * |--List: * |--Set: * |--HashSet(类):哈希表实现; * 保证元素唯一性:hashCode()和equals(); * |--LinkedHashSet(类):由链表、哈希表实现;(特例:有序) * 由"链表"保证顺序; * 由"哈希表"保证元素唯一; */public class Demo {public static void main(String[] args) {//1.实例化一个LinkedHashSetLinkedHashSet<String> strSet = new LinkedHashSet<>();//2.填充集合strSet.add("aaa");strSet.add("bbb");strSet.add("ccc");strSet.add("ddd");//3.遍历for(String s : strSet){System.out.println(s);//有序的;}}}

TreeSet集合:

|--TreeSet:对元素进行排序的;
      排序的方式:
      1.自然排序:
      2.比较器排序:由于涉及到排序,所以就不拿String排序了,直接举例存储自定义元素,实现比较器

示例一:存储自定义对象,自然排序

import java.util.TreeSet;/* * 当使用TreeSet存储自定义对象时: * 1.实现"自然排序": * 1.要存储的元素实现Comparable接口; * 2.并重写compareTo()方法; * 或者 * 2.实现"比较器": * 1.要存储的元素,无需实现任何接口; * 2.自定义比较器类,实现:Comparator接口; *      重写:compare()方法; * 3.在实例化TreeSet时,将自定义的比较器传给TreeSet构造方法; */public class Demo {public static void main(String[] args) {TreeSet<Student> stuSet = new TreeSet<>();stuSet.add(new Student("zhagnxueyou",20));//TreeSet的add()方法中,自动调用元素的compareTo()方法stuSet.add(new Student("liudehua",22));stuSet.add(new Student("zhangziy",24));stuSet.add(new Student("daolang",22));stuSet.add(new Student("chenglong",23));stuSet.add(new Student("kangshifu",25));stuSet.add(new Student("kangshifu",27));//遍历for(Student stu : stuSet){System.out.println(stu.name + "," + stu.age);}}}

public class Student implements Comparable<Student>{String name;int age;public Student(String name, int age) {super();this.name = name;this.age = age;}@Overridepublic int compareTo(Student o) {System.out.println("this.name = " + this.name + " o.name = " + o.name);//1.先按姓名排序int n1 = this.name.compareTo(o.name);//2.如果姓名相同,按年龄排序int n2 = (n1 == 0 ? this.age - o.age : n1);return n2;}}


示例2 :存储自定义对象,比较器排序,因为对象类照常写,这里只展示集合类的写法 

 

import java.util.Comparator;import java.util.TreeSet;public class Demo {public static void main(String[] args) {//1.实例化一个TreeSetTreeSet<Student> stuSet = new TreeSet<>(new MyComparator());stuSet.add(new Student("zhangxueyou",20));stuSet.add(new Student("liudehua",22));stuSet.add(new Student("zhangziyi",24));for(Student stu : stuSet){System.out.println(stu.name + "," + stu.age);}}}class MyComparator implements Comparator<Student>{@Overridepublic int compare(Student o1, Student o2) {System.out.println("o1.name = " + o1.name + " o2.name = " + o2.name);//1.先按姓名比int n1 = o1.name.compareTo(o2.name);//2.如果姓名相同,比较年龄int n2 = (n1 == 0 ? o1.age - o2.age : n1);return n2;}}

Map集合

Map(接口):双列集合:在存储时,同时指定两个字段;一个做"键",一个做"值"(键值对);
 |--HashMap:哈希表结构:
 |--LinkedHashMap:链表、哈希表结构:
 |--TreeMap:树结构:
 以上Map接口的各种"数据结构"全部是针对"键"有效,跟"值"无关

import java.util.HashMap;import java.util.Map;/* * Map接口的基本功能: *  * 注:以下方法中标示为:K的表示:键,V的表示:值 *  * V put(K key,V value) :向集合中添加"键值对",如果发生重复的键,将用新值替换原值,并将原值返回;V remove(Object key):移除key所指定的"键值对"void clear():清空集合boolean containsKey(Object key):判断是否包含指定keyboolean containsValue(Object value):判断是否包含指定的valueboolean isEmpty():判断集合是否为空int size():集合中"键值对"的数量 */public class Demo {public static void main(String[] args) {Map<String,String> map = new HashMap<>();System.out.println(map.put("it001", "刘德华"));System.out.println(map.put("it002", "张学友"));System.out.println("集合元素:" + map);System.out.println(map.put("it002", "章子怡"));//替换原it002对应的值System.out.println("集合元素:" + map);System.out.println("移除掉it001:" + map.remove("it001"));System.out.println("移除后的集合:" + map);//清空集合//map.clear();System.out.println("是否包含键:it001 : " + map.containsKey("it001"));System.out.println("是否包含值:章子怡 : " + map.containsValue("章子怡"));System.out.println("是否包含值:刘德华 :" + map.containsValue("刘德华"));System.out.println("集合是否为空:" + map.isEmpty());System.out.println("集合中元素数量:" + map.size());}


Map的获取功能:
  V get(Object key):使用指定key查找对应"值"
 Set<K> keySet():获取所有的"键"的集合(Set集合)
 Collection<V> values():获取所有"值"的集合(Collection集合)
 Set<Map.Entry<K,V>> entrySet():返回所有的"键值对-对象";Entry是Map的内部类;
                                 一个Entry内部封装了一个"键"和一个"值"

public class Demo {public static void main(String[] args) {Map<String,String> map = new HashMap<>();map.put("it001", "刘德华");map.put("it002", "张学友");map.put("it003", "郭富城");map.put("it004", "黎明");System.out.println("it003对应的值:" + map.get("it003"));Set<String> keys = map.keySet();//遍历键的集合for(String key : keys){System.out.println(key + "," + map.get(key));}System.out.println("******获取所有的值**********");Collection<String> values = map.values();for(String v : values){System.out.println(v);}System.out.println("******获取所有的键值对--对象*******");Set<Map.Entry<String, String>> entrySet = map.entrySet();for(Map.Entry<String, String> m : entrySet){String key = m.getKey();String value = m.getValue();System.out.println(key + "," + value);}}}

map集合中键是基本数据类型和String类型的比较简单,这里主要整理键是自定义类型时候的问题,因为当键是自定义类型的时候,需要重写一些方法:

import java.util.HashMap;import java.util.Map;import java.util.Set;/* * HashMap集合键是Student值是String的案例 *  * 1.由于Student做键,HashMap对键使用"哈希表结构",要判断键的重复性,使用hashCode()和equals() * 2.所以,使用自定义做键,要重写hashCode和equals()方法; *  */public class Demo {public static void main(String[] args) {Map<Student , String> map = new HashMap<>();//填充集合map.put(new Student("张学友",20), "it001");map.put(new Student("刘德华",22), "it002");map.put(new Student("张曼玉",18), "it003");map.put(new Student("章子怡",19), "it004");map.put(new Student("章子怡",19), "it005");Set<Map.Entry<Student,String>> entrySet = map.entrySet();for(Map.Entry<Student, String> e : entrySet){Student stu = e.getKey();String value = e.getValue();System.out.println("键:" + stu.name + "," + stu.age + " 值:" + value);}}}

链表哈希表结构:特点:有序,谁保证顺序:链表

import java.util.LinkedHashMap;import java.util.Map;import java.util.Set;/* * LinkedHashMap的概述和使用 *  * 1.有序的;由链表保证顺序; * 2.由哈希表保证元素唯一; */public class Demo {public static void main(String[] args) {//1.实例化一个LinkedHashMapMap<String,String> map = new LinkedHashMap<>();//2.填充集合map.put("it001", "刘德华");map.put("it002", "张学友");map.put("it003", "章子怡");map.put("it004", "刘亦菲");map.put("it004", "高圆圆");//3.遍历集合Set<String> keys = map.keySet();for(String key : keys){System.out.println(key + "," + map.get(key));//取出时,跟存入的顺序是一样的;}}}

最后,是Treemap集合的知识,Treemap是排序的双列集合,底层是数结构:这里使用匿名内部类的方式实现比较器

import java.util.Comparator;import java.util.Set;import java.util.TreeMap;/* * TreeMap集合键是Student值是String的案例 *  * 自定义对象做键,必须实现两种比较的方式之一;
*/public class Demo {public static void main(String[] args) {//1.实例化一个对象TreeMap<Student,String> map = new TreeMap<>(new Comparator<Student>(){@Overridepublic int compare(Student o1, Student o2) {//1.先按姓名排序int n1 = o1.name.compareTo(o2.name);//2.如果姓名相同,按年龄排序int n2 = (n1 == 0 ? o1.age - o2.age : n1);return n2;}});//2.填充集合map.put(new Student("刘德华",20), "it001");map.put(new Student("张学友",22), "it002");map.put(new Student("章子怡",24), "it003");map.put(new Student("章子怡",24), "it004");Set<Student> keys = map.keySet();for(Student stu : keys){System.out.println("键:" + stu.name + "," + stu.age + " 值:" + map.get(stu));}}}


 


import java.util.Comparator;import java.util.Set;import java.util.TreeMap;/* * TreeMap集合键是Student值是String的案例 *  * 自定义对象做键,必须实现两种比较的方式之一; */public class Demo {public static void main(String[] args) {//1.实例化一个对象TreeMap<Student,String> map = new TreeMap<>(new Comparator<Student>(){@Overridepublic int compare(Student o1, Student o2) {//1.先按姓名排序int n1 = o1.name.compareTo(o2.name);//2.如果姓名相同,按年龄排序int n2 = (n1 == 0 ? o1.age - o2.age : n1);return n2;}});//2.填充集合map.put(new Student("刘德华",20), "it001");map.put(new Student("张学友",22), "it002");map.put(new Student("章子怡",24), "it003");map.put(new Student("章子怡",24), "it004");Set<Student> keys = map.keySet();for(Student stu : keys){System.out.println("键:" + stu.name + "," + stu.age + " 值:" + map.get(stu));}}

集合工具类:

集合的工具类:java.util.Collections(工具类):里面包含了一些对Collection集合操作的一些常用方法;

 1.之前我们讲过数组的工具类:Arrays;它是对数组操作的工具类;

 2.还学过一个接口Collection,它是List和Set集合的顶层接口;
 
 Collections工具类的常用方法:
 public static <T> void sort(List<T> list):根据元素的自然顺序 对指定列表按升序进行排序;
 public static <T> int binarySearch(List<?> list,T key)使用二分搜索法搜索指定列表,以获得指定对象。在进行此调用之前,必须根据列表元素的自然顺序对列表进行升序排序(通过 sort(List) 方法)。
 public static <T> T max(Collection<?> coll): 查找参数coll集合中的最大值;
 public static void reverse(List<?> list):反转指定列表中元素的顺序。
 public static void shuffle(List<?> list):打乱集合内元素的顺序;

 

一个比较重要的小知识:hashmap和hashtable的区别:

import java.util.HashMap;import java.util.Hashtable;import java.util.Map;/* * 面试题:HashMap和Hashtable的区别 *  * Hashtable: * 1.任何非 null 对象都可以用作键或值 * 2.从1.0版本开始; * 3.线程安全的(同步的),效率低; * HashMap: * 1.允许使用 null 值和 null 键 * 2.从1.2版本开始; * 3.线程不安全的(非同步的),效率高; */public class Demo {public static void main(String[] args) {Map<String,String> table = new Hashtable<>();table.put("it001", "郑智");//table.put(null, "郜林");//空指针异常//table.put("it002", null);//空指针异常Map<String,String> map = new HashMap<>();map.put(null, "郑智");map.put("it002", null);map.put("it003", null);map.put("it004", null);map.put(null, "郜林");System.out.println("map = " + map);}}

最后,做一个集合知识框架最终结构图:

一.集合的特点和数据结构总结
 Collection(接口):单列集合
  |--List(接口):1.有序的;2.可以存储重复值;
   |--ArrayList(类):数组实现;线程不安全的(不同步),效率高;
   |--Vector(类):数组实现;线程安全的(同步),效率低;
   |--LinkedList(类):链表;线程不安全的(不同步),效率高;
  |--Set(接口):1.无序的;2.不能存储重复值;
   |--HashSet(类):哈希表实现;
    保证元素唯一性的方法:hashCode()和equals()方法;
   |--LinkedHashSet(类):链表、哈希表实现;(特例:有序的)
    链表:保证顺序;
    哈希表:保证元素唯一;
   |--TreeSet(类):树实现;
    对元素排序和保证元素唯一的方法:
    1.自然排序:
     1).要存储的元素实现Comparable接口
     2).重写compareTo()方法;
    2.比较器排序:
     1).要自定义比较器,实现Comparator接口;
     2).重写compare()方法;
     3).实例化TreeSet时,将自定义比较器对象作为参数传递给TreeSet的构造方法;

 Map(接口):双列集合
  |--HashMap(类):键:哈希表结构:
  |--LinkedHashMap(类):键:链表、哈希表结构
  |--TreeMap(类):键:树结构
  |--Hashtable(类):键:哈希表结构;

 HashMap和Hashtable的区别:
 1.Hashtable:
  1).不能存储null键和null值;
  2).从1.0版本开始;
  3).线程安全的(同步),效率低;
 2.HashMap:
  1).可以存储null键和null值;
  2).从1.2版本开始;
  3).线程不安全的(不同步),效率高;

二.数据结构:
 1.数组:查询快;增删慢;
 2.链表:查询慢;增删快;
 3.栈:先进后出;
 4.队列:先进先出;
 5.哈希表:综合了数组和链表的优点,增删、查询都很快,关键是取决于:哈希算法;
 6.树:对元素进行排序;
  1).比当前节点元素小,存到左边;
  2).比当前节点元素大,存到右边;
  3).如果相等,不存;

三.如何选择使用哪种集合呢:
 单列还是双列:
 单列:Collection:
  |--有序无序;是否存储不重复:
   |--有序:
    ArrayList、Vector、LinkedList
   |--无序:
    HashSet(不重复)、LinkedHashSet(有序,不重复)、TreeSet(排序、不重复)
 
 双列:Map
  |--是否有序:
   |--是:LinkedHashMap
    |--是否排序:
     |--是:TreeMap
   |--否:HashMap
四.遍历方式总结:
 Collection(接口):
  |--(1).toArray():
  |--(2).iterator():迭代器
  |--(3).增强for
   |--List(接口):
    |--(4).结合Collection的size和List的get()方法,使用普通for循环;
    |--(5).ListIterator():可以双向遍历;
   |--Set(接口):
    (无特有遍历方式)
 Map(接口):
  (1).keySet():
  (2).entrySet():

 

 

最后,做一个集合知识框架最终结构图:

一.集合的特点和数据结构总结
 Collection(接口):单列集合
  |--List(接口):1.有序的;2.可以存储重复值;
   |--ArrayList(类):数组实现;线程不安全的(不同步),效率高;
   |--Vector(类):数组实现;线程安全的(同步),效率低;
   |--LinkedList(类):链表;线程不安全的(不同步),效率高;
  |--Set(接口):1.无序的;2.不能存储重复值;
   |--HashSet(类):哈希表实现;
    保证元素唯一性的方法:hashCode()和equals()方法;
   |--LinkedHashSet(类):链表、哈希表实现;(特例:有序的)
    链表:保证顺序;
    哈希表:保证元素唯一;
   |--TreeSet(类):树实现;
    对元素排序和保证元素唯一的方法:
    1.自然排序:
     1).要存储的元素实现Comparable接口
     2).重写compareTo()方法;
    2.比较器排序:
     1).要自定义比较器,实现Comparator接口;
     2).重写compare()方法;
     3).实例化TreeSet时,将自定义比较器对象作为参数传递给TreeSet的构造方法;

 Map(接口):双列集合
  |--HashMap(类):键:哈希表结构:
  |--LinkedHashMap(类):键:链表、哈希表结构
  |--TreeMap(类):键:树结构
  |--Hashtable(类):键:哈希表结构;

 HashMap和Hashtable的区别:
 1.Hashtable:
  1).不能存储null键和null值;
  2).从1.0版本开始;
  3).线程安全的(同步),效率低;
 2.HashMap:
  1).可以存储null键和null值;
  2).从1.2版本开始;
  3).线程不安全的(不同步),效率高;

二.数据结构:
 1.数组:查询快;增删慢;
 2.链表:查询慢;增删快;
 3.栈:先进后出;
 4.队列:先进先出;
 5.哈希表:综合了数组和链表的优点,增删、查询都很快,关键是取决于:哈希算法;
 6.树:对元素进行排序;
  1).比当前节点元素小,存到左边;
  2).比当前节点元素大,存到右边;
  3).如果相等,不存;

三.如何选择使用哪种集合呢:
 单列还是双列:
 单列:Collection:
  |--有序无序;是否存储不重复:
   |--有序:
    ArrayList、Vector、LinkedList
   |--无序:
    HashSet(不重复)、LinkedHashSet(有序,不重复)、TreeSet(排序、不重复)
 
 双列:Map
  |--是否有序:
   |--是:LinkedHashMap
    |--是否排序:
     |--是:TreeMap
   |--否:HashMap
四.遍历方式总结:
 Collection(接口):
  |--(1).toArray():
  |--(2).iterator():迭代器
  |--(3).增强for
   |--List(接口):
    |--(4).结合Collection的size和List的get()方法,使用普通for循环;
    |--(5).ListIterator():可以双向遍历;
   |--Set(接口):
    (无特有遍历方式)
 Map(接口):
  (1).keySet():
  (2).entrySet():

 

 


 

0 0