美文网首页
JAVA基础之集合框架详解

JAVA基础之集合框架详解

作者: Owen270 | 来源:发表于2018-09-18 16:47 被阅读6次

    参考文章:
    https://www.cnblogs.com/xiaoxi/p/6089984.html
    http://www.importnew.com/16658.html

    1.集合框架图

    Java的集合类主要由两个接口派生而出:Collection和Map,Collection和Map是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

    同样实现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<String> 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<String> 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<String> 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<String> hashSet=new HashSet<>();
            hashSet.add("javabbb");
            hashSet.add("java01");
            hashSet.add("java01");
            hashSet.add("java03");
            hashSet.add("java02");
            Set<String>  hashSet1=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<String> iterator= hashSet.iterator();
            while (iterator.hasNext()){
                System.out.println(iterator.next());
            }
        }
    

    输出结果:


    image.png
    (2)LinkedHashSet

    LinkedHashSet继承自HashSet,其底层是基于LinkedHashMap来实现的,有序,非同步。LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。

    注意:LinkedHashSet底层是基于LinkedHashMap来实现
     private static void testLinkedHashSet() {
            /****
             * 因为是链表,所以有序输出
             * 元素不重复
             */
            Set<String> linkedHashSet=new LinkedHashSet<>();
            linkedHashSet.add("java01");
            linkedHashSet.add("java01");
            linkedHashSet.add("java02");
            linkedHashSet.add("java03");
            Set<String> linkedHashSet1=new LinkedHashSet<>();
            linkedHashSet1.add("java04");
            linkedHashSet1.add("java05");
            linkedHashSet1.add(null);
            linkedHashSet1.add(null);
            linkedHashSet.addAll(linkedHashSet1);
            //遍历
            Iterator<String> iterator= linkedHashSet.iterator();
            while (iterator.hasNext()){
                System.out.println(iterator.next());
            }
    
        }
    

    输出结果:


    image.png
    (3)TreeSet

    TreeSet是一个有序集合,其底层是基于TreeMap实现的,非线程安全。TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序和定制排序,其中自然排序为默认的排序方式。当我们构造TreeSet时,若使用不带参数的构造函数,则TreeSet的使用自然比较器;若用户需要使用自定义的比较器,则需要使用带比较器的参数。

    注意:TreeSet底层是基于TreeMap来实现,Set集合都是非线程安全的
    
        private static void testIntegerSort() {
            System.out.println("Integer对象自然排序:");
            TreeSet<Integer> treeSetFirst = new TreeSet<>();
            treeSetFirst.add(2);
            treeSetFirst.add(1);
            treeSetFirst.add(4);
            treeSetFirst.add(3);
            treeSetFirst.add(5);
            Iterator<Integer> iterator=treeSetFirst.iterator();
            while (iterator.hasNext()){
                    System.out.println(iterator.next());
            }
        }
        private static void testDictionarySort() {
            System.out.println("Dictionary对象自然排序:");
            TreeSet<String> 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<String> iterator=treeSetFirst.iterator();
            while (iterator.hasNext()){
                System.out.println(iterator.next());
            }
        }
    
    
        private static void testCompatorSort() {
            Set<Student> 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<student.getNum()){//升序排列
                    return -1;
                }else if(num==student.getNum()){
                    return name.compareTo(student.getName());
                }else{
                    return 1;
                }
    
            }
        }
    
    

    输出结果:


    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<String, String> 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));
            }
        }
    

    输出结果:


    image.png

    输出结果:


    image.png

    (2).LinkedHashMap

    LinkedHashMap是HashMap的一个子类,它保留插入的顺序,如果需要输出的顺序和输入时的相同,那么就选用LinkedHashMap。允许使用null值和null键

    private static void testLinkHashMap() {
            //linkedhashmap  extends hashmap 比hashmap功能更强大
            Map<String, String> 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));
            }
        }
    

    输出结果:


    image.png

    (2).Hashtable

    线程同步,同时key,value都不可以为null,无序的

    private static void testHashtable() {
            /***
             * 线程同步的,同时key,value都不可以为null,无序的
             */
            Hashtable<String,Object> 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<String,Object> 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));
            }
        }
    

    输出结果:


    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<Integer,String> treeMapFirst = new TreeMap<Integer, String>();
            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<SortedTest,String> treeMapSecond = new TreeMap<SortedTest, String>();
            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<String,SortedTest> treeMapThree = new TreeMap<String,SortedTest >();
            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<SortedTest> {
            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;
                }
            }
        }
    
    

    输出结果:


    image.png

    相关文章

      网友评论

          本文标题:JAVA基础之集合框架详解

          本文链接:https://www.haomeiwen.com/subject/yhwpnftx.html