zoukankan      html  css  js  c++  java
  • JAVA 集合

    一、概念

    能够存放一个或一组对象的容器,就叫做集合,他是一套功能完善的数据结构。(也叫做容器 也叫做集合框架)

    二、集合一览表

    集合类型 描述
    ArrayList 一种可以动态增长和缩减的索引序列
    LinkedList 一种可以在任何位置进行高效的插入和删除操作的有序序列
    ArrayDeque 一种用循环数组实现的双端队列
    HashSet 一种没有重复元素的无序集合
    TreeSet 一种没有重复元素的有序集合
    EnumSet 一种包含枚举类型值的集合
    LinkedHashSet 一种按照插入顺序来存储元素的集合
    PriorityQueue 一种允许高效删除最小元素的队列集合
    HashMap 一种存储键值对的映射表
    TreeMap 一种有序存储键值对的映射表
    EnumMap 一种键值属于枚举类型的映射表
    LinkedHashMap 一种按照插入顺序来存储元素的映射表
    WeakHashMap 一种当值不再被使用时可以自动被垃圾回收器回收的映射表
    IdentityHashMap 一种用==而不是用equals比较键值的映射表

    三、Collection家族

    ArrayList

    在java中,数组的长度是固定的,数组在创建之后,就不能增长或减小,ArrayList就是用来解决这个问题的,ArrayList的长度可以自动增加和减小。

            ArrayList a1 = new ArrayList<>();//不限存储类型 啥都能往里塞
            ArrayList<String> a2 = new ArrayList<>();//只能存储String类型
            ArrayList<Integer> a3 = new ArrayList<>(Arrays.asList(2,4,5));//将一个Collection集合初始化成ArrayList
            ArrayList<Integer> a4 = new ArrayList<>(10);//指定初始化大小
            ArrayList<String> a1 = new ArrayList<>();
            System.out.println(a1.toString()+" 集合长度是:"+a1.size());//output:[] 数组长度是:0
    
            a1.add("a");
            a1.add("c");
            a1.add(1,"b");//指定插入位置
            System.out.println(a1.toString()+" 集合长度是:"+a1.size());//output:[a, b, c] 数组长度是:3
    
            a1.addAll(Arrays.asList("d","e","f"));//插入一个数组
            System.out.println(a1.toString()+" 集合长度是:"+a1.size());//output:[a, b, c, d, e, f] 数组长度是:6
    
            a1.remove("a");//移除对象
            a1.remove(1);//移除该索引的对象
            System.out.println(a1.toString()+" 集合长度是:"+a1.size());//output:[b, d, e, f] 数组长度是:4
    
            //可以看出  a1一开始是空的,随着数据的插入,a1的长度在自动增长,随着数据的移除,a1的长度在自动减小。
            //移除a对象后,b的索引就变成了0,所以移除索引1的对象实际上是移除了c
    
            //ArrayList转数组
            String a2[] = new String[a1.size()];
            a2 = a1.toArray(a2);
    
            for(String a : a2){
                System.out.print(" 遍历数组"+a);
            }
            //output:遍历数组b 遍历数组d 遍历数组e 遍历数组f

    LinkedList

    ArrayList的缺陷是从中间位置删除元素要付出的代价非常大,因为处于中间被删除的元素之后的所有元素都要向列表的前端移动,从中间插入元素同理。
    链表就解决了这个问题,链表中每一个对象都存在独立的节点中,每个节点拥有3个东西,一个是存储的对象,另外两个是标记,指向上一个节点和下一个节点的引用。删除数据时只需要更改标记引用即可,

            LinkedList<Integer> a1 = new LinkedList<>();//创建一个空链表
            LinkedList<Integer> a2 = new LinkedList<>(Arrays.asList(2,5,6));//将一个Collection集合初始化成LinkedList
            LinkedList<String> a1 = new LinkedList<>();
            a1.add("A");
            a1.add("C");
            a1.add(1,"B");//添加到指定位置
            System.out.println(a1);//output:[A, C, B]
    
            a1.addFirst("A0");//添加到头部
            System.out.println(a1);//output:[A0, A, B, C]
    
            a1.addLast("D");//添加到尾部
            System.out.println(a1);//output:[A0, A, B, C, D]
    
            String s1 = a1.getFirst();//获取头部元素
            System.out.println(s1);//output:A0
    
            String s2 = a1.getLast();//获取尾部元素
            System.out.println(s2);//output:D
    
            String s3 = a1.get(1);//获取指定位置的元素
            System.out.println(s3);//output:A
    
            a1.remove("B");//移除元素
            System.out.println(a1);//output:[A0, A, C, D]
    
            a1.remove(1);//移除指定位置的元素
            System.out.println(a1);//output:[A0, C, D]
    
            a1.removeFirst();//移除第一个元素
            System.out.println(a1);//output:[C, D]
    
            a1.removeLast();//移除最后一个元素
            System.out.println(a1);//output:[C]

    HashSet

    有一种叫散列表的数据结构可以快速的查找所需要的对象,java提供了一个基于散列表的实现,HashSet,它的特点是速度快,无重复。

            HashSet<Integer> a1 = new HashSet();//创建一个HashSet
            HashSet<Integer> a2 = new HashSet(Arrays.asList(2.5,6));//将一个Collection集合初始化成HashSet
            HashSet<Integer> aa = new HashSet<>();
            aa.add(2);
            aa.add(22);
            aa.add(55);
            aa.add(23);
            aa.add(35);
            aa.add(15);
            aa.add(19);
            aa.add(6);
            System.out.println(aa);//output:[2, 35, 19, 22, 6, 55, 23, 15]
    
            HashSet<String> a1 = new HashSet<>();
            a1.add("A");
            a1.add("A");
            a1.add("B");
            a1.add("D");
            a1.add("C");
            System.out.println(a1);//output:[A, B, C, D]
    
            int s = a1.size();
            System.out.println(s);//output:4
    
            a1.remove("A");
            System.out.println(a1);//output:[B, C, D]

    可以发现 插入的顺序并不是存储的顺序,存储是无序的,但如果是说它是随机的我肯定不信,因为每次运行的打印结果都是一样的。

    LinkedHashSet

    LinkedHashSet扩展了HashSet类,他的方法和HashSet完全一样,唯一的特点是它是链表实现,他的存储顺序完全就是插入顺序。

            HashSet<Integer> a1 = new LinkedHashSet<>();//创建一个LinkedHashSet
            HashSet<Integer> a2 = new LinkedHashSet(Arrays.asList(2.5,6));//将一个Collection集合初始化成LinkedHashSet
            LinkedHashSet<String> a1 = new LinkedHashSet<>();
            a1.add("A");
            a1.add("A");
            a1.add("B");
            a1.add("D");
            a1.add("C");
            System.out.println(a1);//output:[A, B, D, C]
    
            int s = a1.size();
            System.out.println(s);//output:4
    
            a1.remove("A");
            System.out.println(a1);//output:[B, D, C]

    TreeSet

    TreeSet与散列集十分类似,它比散列集有所改进,树是一个有序集合,在添加元素时它会在内部进行比较排序,将元素添加到合适的位置,所以选不选用TreeSet的判断条件是需不需要排序

            TreeSet<Integer> a1 = new TreeSet<>();
            TreeSet<Integer> a2 = new TreeSet<>(Arrays.asList(2,5,6));
            TreeSet<Integer> a1 = new TreeSet<>();
            a1.add(22);
            a1.add(53);
            a1.add(66);
            a1.add(9);
            a1.add(12);
            a1.add(27);
            a1.add(19);
            a1.add(35);
            System.out.println(a1);//output:[9, 12, 19, 22, 27, 35, 53, 66]
    
            TreeSet<Integer> a2 = new TreeSet<>(a1.subSet(10,30));//获取a1中10到30的元素 组成新树
            System.out.println(a2);//[12, 19, 22, 27]

    PriorityQueue

    优先级队列中的元素可以按照任意的顺序插入,却总是按照排序的顺序进行检索,它使用了一个高效的数据结构,叫做堆,堆是一个可以自我调整的二叉树,堆树执行添加和删除操作,可以让最小的元素移动到根,从而不比花费时间对元素进行排序。

            PriorityQueue<Integer> a1 = new PriorityQueue<>();
            PriorityQueue<Integer> a2 = new PriorityQueue<>(Arrays.asList(2,5,3));
            PriorityQueue<Integer> a3 = new PriorityQueue<>(Comparator.reverseOrder());//指定排序比较器
            PriorityQueue<Integer> a1 = new PriorityQueue<>(Comparator.naturalOrder());
            a1.add(88);
            a1.add(34);
            a1.add(54);
            a1.add(26);
            a1.add(62);
            a1.add(19);
            System.out.println(a1);//output:[19, 34, 26, 88, 62, 54]
    
            a1.remove();//默认删除队列最前端元素
            System.out.println(a1);//output:[26, 34, 54, 88, 62]
    
            a1.remove(54);//删除指定元素
            System.out.println(a1);//output:[26, 34, 62, 88]
    
            a1.offer(3);//往队列出口压入元素
            System.out.println(a1);//output:[3, 26, 62, 88, 34]
    
            System.out.println(a1.peek());//偷看元素 output:3
    
            System.out.println(a1);//output:[3, 26, 62, 88, 34]
    
            System.out.println(a1.poll());//弹出元素 output:3
    
            System.out.println(a1);//output:[26, 34, 62, 88]

    四、Map家族

    HashMap

    散列映射,HashMap实现了Map接口,它使用哈希表存储映射,这使得即使对于比较大的集合,它的存取执行时间都是非常高效的。

            HashMap map = new HashMap();
            map.put("a","第一个元素a");
            map.put("b","第二个元素b");
            map.put("c","第三个元素c");
            System.out.println(map);
    
            //遍历方式1
            Set<Map.Entry<String,String>> set = map.entrySet();
            for(Map.Entry<String,String> m : set){
                System.out.println("key="+m.getKey()+" value="+m.getValue());
            }
    
            //遍历方式2
            map.forEach((k,v)-> System.out.println("key="+k+" value="+v));

    TreeMap

    树映射,TreeMap也实现了Map接口,它与HashMap的使用方式一样,因此就不贴重复的代码了,不同的是,TreeMap是默认以键的升序存储。

    那么应该选择散列映射还是树映射呢?答案是散列稍微快一些,如果不需要按照排序存储,那么最好选择散列。

    五、个人分享

    悄悄话

    1.Collection 存放一行一行的数据 可以想成mysql的表 只不过这个表只有两个字段 第一个字段是索引,第二个字段是存储对象, 可以理解成索引数组
    2.Map 键值对 Json redis 关联数组 怎么理解都没错

    3.集合中只能存储对象,当你存储基本类型时,它会自动装箱再存储,同理,用基本类型接收时,会有自动拆箱的过程。

    源码分享

    Fork me on Gitee

  • 相关阅读:
    死磕算法第一弹——数组、集合与散列表
    拼写纠正
    IntelliJ系列IDE中的project和module
    【Spring】学习SpringAOP
    MyEclipse打开Jsp报错Failed to create the part's controls
    【Spring】学习SpringIoC
    【GitHub】Set up GitHub for Win10
    【<meta name="" content=">】的作用
    【JSP】修改网页ico小图标
    【JSP】导航栏悬停顶部简单特效
  • 原文地址:https://www.cnblogs.com/fengyumeng/p/9858631.html
Copyright © 2011-2022 走看看