• JAVA-集合框架篇


    集合

    • 概念:对象的容器,定义了对多个对象进行操作的常用方法,可实现数组的功能
      与数组的区别:
    1. 数组长度固定,集合长度不固定
    2. 数组可以存储基本数据类型和引用类型,集合只能存储引用类型,当储存基本数据类型的时候会自动装箱
    • 位置:java.util.*;

    Collection

    在这里插入图片描述
    在这里插入图片描述

    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Iterator;
    
    public class Test11 {
        public static void main(String[] args) {
            //todo 创建集合
            Collection  collection = new ArrayList();
            //todo 添加元素
            collection.add("chen");
            collection.add("xing");
            collection.add("en");
            // 获取集合大小
            System.out.println(collection.size());
            //删除元素
            collection.remove("chen");
            System.out.println(collection.size());
            //遍历集合
            // todo 1.使用增强for循环遍历
            for (Object o : collection) {
                System.out.println(o);
            }
            // todo 2.使用迭代器
            Iterator iterator = collection.iterator();
            while (iterator.hasNext()){
                Object o=iterator.next();
                System.out.println(o);
                //迭代器内不允许使用collection.remove();
                //可以使用iterator.remove();
            }
            //todo 判断集合中是否有某元素
            System.out.println(collection.contains("xin"));
            System.out.println(collection.contains("xing"));
    
    		 // todo 判断集合是否为null
            System.out.println(collection.isEmpty());
            // todo 清空集合
            collection.clear();
            System.out.println(collection.isEmpty());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    List

    特点:有序(添加顺序与遍历顺序)、有下标、元素可重复
    在这里插入图片描述

    import java.util.ArrayList;
    import java.util.List;
    import java.util.ListIterator;
    
    public class Test12 {
        public static void main(String[] args) {
            List objects = new ArrayList<>();
            objects.add("chen");
            objects.add("cx");
            // todo 角标遍历
            for (int i=0;i<objects.size();i++){
                System.out.println(objects.get(i));
            }
            // todo 使用列表迭代器
            ListIterator listIterator = objects.listIterator();
    
            while(listIterator.hasNext()){
                System.out.println(listIterator.nextIndex()+":"+listIterator.next());
            }
            //指针,所以必须先使用hasNext
            while(listIterator.hasPrevious()){
                System.out.println(listIterator.previousIndex()+":"+listIterator.previous());
            }
    
            //判断
            System.out.println(objects.contains("chen"));
            System.out.println(objects.isEmpty());
            //获取位置
            System.out.println(objects.indexOf("cx"));
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    import java.util.ArrayList;
    import java.util.List;
    
    public class Test13 {
        public static void main(String[] args) {
            List objects = new ArrayList<>();
            //进行了自动装箱处理
            objects.add(20);
            objects.add(30);
            System.out.println(objects.size());
            //截取,含头不含尾
            System.out.println(objects.subList(1,2));
            //删除操作
            objects.remove(0);
            //objects.remove(20);此处是索引
            System.out.println(objects);
            objects.remove(new Integer(30));
            System.out.println(objects);//[]
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • ArrayList
      1.数据结构实现,查询快,增删慢;
      2.JDK1.2版本,运行效率快、线程不安全
    • Vector
      1.数组结构实现,查询快、增删慢;
      2.JDK1.0版本,运行效率慢、线程安全
    • LinkedList
      1.链表结构实现,增删快,查询慢

    ArrayList

    创建ArrayList初始容量为0 ,当添加第一个元素时,容量变为10,扩容时,每次为前一次的1.5倍

    public class Student implements Serializable {
        private String name;
        private String age;
    
        public Student() {
        }
    
        public Student(String name, String age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAge() {
            return age;
        }
    
        public void setAge(String age) {
            this.age = age;
        }
    
        //重写比较方法
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Student student = (Student) o;
            return name.equals(student.name) && age.equals(student.age);
        }
    
        //重写toString方法
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age='" + age + '\'' +
                    '}';
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    public class Test14 {
        public static void main(String[] args) {
            ArrayList<Object> objects = new ArrayList<>();
            objects.add(new Student("12","c"));
            objects.add(new Student("12","x"));
            System.out.println(objects);
            //删除元素,此时需要重写equals方法,才能删除列表中的Student("12","c")
            objects.remove(new Student("12","c"));
            System.out.println(objects);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    LinkedList

    public class Test18 {
        public static void main(String[] args) {
            LinkedList<Object> objects = new LinkedList<>();
            objects.add("c");
            objects.add("x");
            //迭代器遍历
            Iterator<Object> iterator = objects.iterator();
            while (iterator.hasNext()){
                Object next = iterator.next();
                System.out.println(next);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    Vector

    
    public class Test17 {
        public static void main(String[] args) {
            Vector<Object> objects = new Vector<>();
            objects.add("c");
            objects.add("x");
            System.out.println(objects.size());
            //遍历:使用枚举器
            Enumeration<Object> elements = objects.elements();
            while (elements.hasMoreElements()){
                Object o = elements.nextElement();
                System.out.println(o);
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    Set

    特点:无序(添加顺序与遍历顺序)、无下标、元素不可重复

    HashSet

    • 基于HashCode实现元素不重复。
    • 当存入元素的哈希码相同时,会调用equals进行确认,若结果为true,则拒绝后者存入
    • 底层实际是用的HashMap
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    
    public class Test21 {
        public static void main(String[] args) {
            Set<String> objects = new HashSet<String>();
            objects.add("c");
            objects.add("x");
            System.out.println(objects.size());
            //迭代器遍历
            Iterator<String> iterator = objects.iterator();
            while (iterator.hasNext()){
                String next = iterator.next();
                System.out.println(next);
            }
            boolean x = objects.contains("x");
            System.out.println(x);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20


    package com.utils;
    
    import java.io.Serializable;
    import java.util.Objects;
    
    public class Student implements Serializable {
        private String name;
        private String age;
    
        public Student() {
        }
    
        public Student(String name, String age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAge() {
            return age;
        }
    
        public void setAge(String age) {
            this.age = age;
        }
    
        //重写比较方法
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Student student = (Student) o;
            return name.equals(student.name) && age.equals(student.age);
        }
    
        //重写toString方法
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age='" + age + '\'' +
                    '}';
        }
    
       //重写hashcode
        @Override
        public int hashCode() {
            //31 是一个质数,减少散列冲突,提高执行效率 31*i=(i<<5)-i
            final  int prime=31;
            int result=1;
            result=prime*result+((this.name==null)?0:(this.name.hashCode()));
            result=prime*result+((this.age==null)?0:(this.age.hashCode()));
            return result;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    package com.utils;
    
    import java.util.HashSet;
    
    /**
     * 存储结构:哈希表(数组+链表+红黑树)
     * 存储过程:
     * 根据hashcode计算保存的位置,如果此位置为空,则直接保存,如果不为空执行第二步,
     * 再执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表
     */
    public class Test22 {
        public static void main(String[] args) {
            HashSet<Student> students = new HashSet<>();
            Student student1 = new Student("c","1");
            Student student2 = new Student("x","2");
            students.add(student1);
            students.add(student2);
            //此时加不进来
            students.add(new Student("x","2"));
            System.out.println(students.toString());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    TreeSet

    • 基于排列顺序实现元素不重复
    • 实现了SortedSet接口,对集合元素自动排序
    • 元素对象的类型必须实现Comparable接口,指定排序规则
    • 通过CompareTo方法确定是否为重复元素
    package com.utils;
    
    import java.io.Serializable;
    import java.util.Objects;
    
    public class Student implements Serializable,Comparable<Student>{
        private String name;
        private String age;
    
        public Student() {
        }
    
        public Student(String name, String age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAge() {
            return age;
        }
    
        public void setAge(String age) {
            this.age = age;
        }
    
        //重写比较方法
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Student student = (Student) o;
            return name.equals(student.name) && age.equals(student.age);
        }
    
        //重写toString方法
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age='" + age + '\'' +
                    '}';
        }
    
        //重写hashcode
        @Override
        public int hashCode() {
            //31 是一个质数,减少散列冲突,提高执行效率 31*i=(i<<5)-i
            final  int prime=31;
            int result=1;
            result=prime*result+((this.name==null)?0:(this.name.hashCode()));
            result=prime*result+((this.age==null)?0:(this.age.hashCode()));
            return result;
        }
    
        //按姓名比,再按年龄比
        @Override
        public int compareTo(Student o) {
            int n1=this.getName().compareTo(o.getName());
            int n2=this.getAge().compareTo(o.getAge());
            return n1==0?n2:n1;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    
    /**
     * 存储结构:红黑树
     * 要求:元素必须要实现Comparable接口
     */
    public class Test23 {
        public static void main(String[] args) {
            TreeSet<Student> students = new TreeSet<Student>();
            Student student4 = new Student("cx","3");
            Student student1 = new Student("cx","1");
            Student student2 = new Student("zx","3");
            Student student3 = new Student("zx","2");
            students.add(student1);
            students.add(student2);
            students.add(student3);
            students.add(student4);
            System.out.println(students.toString());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    Comparator接口

    import java.util.Comparator;
    import java.util.TreeSet;
    
    /**
     * Comparator实现定制比较
     */
    public class Test24 {
        public static void main(String[] args) {
            //创建集合并指定比较规则
            TreeSet<Student> students1 = new TreeSet<>(new Comparator<Student>() {
                @Override
                public int compare(Student o1, Student o2) {
                    int n1=o1.getName().compareTo(o2.getName());
                    int n2=o2.getAge().compareTo(o2.getAge());
                    return n1==0?n2:n1;
                }
            });
            //Student student4 = new Student("cxc","3");
            //Student student1 = new Student("cxc","1");
            Student student2 = new Student("zxz","3");
            Student student3 = new Student("zxz","21");
            //students.add(student1);
            students1.add(student2);
            students1.add(student3);
            //students.add(student4);
            System.out.println(students1.toString());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    Iterator

    Map

    用于存储任意键值对(Key-Value),无序、无下标、键不允许重复(唯一),值可以
    在这里插入图片描述

    • 常用方法
      在这里插入图片描述
    public class Test25 {
        public static void main(String[] args) {
    
            Map<String, String> stringStringHashMap = new HashMap<String, String>();
            stringStringHashMap.put("cx","12");
            stringStringHashMap.put("zx","13");
            stringStringHashMap.put("vx","14");
            //遍历keySet
            Set<String> strings = stringStringHashMap.keySet();
            for (String key : strings) {
                System.out.println(key+":"+stringStringHashMap.get(key));
            }
    
            //entrySet
            Set<Map.Entry<String, String>> entries = stringStringHashMap.entrySet();
            for (Map.Entry<String, String> entry : entries) {
                System.out.println(entry.getKey()+":"+entry.getValue());
            }
        }
        
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    HashMap

    • 存储结构:哈希表
    • 重复依据:键的hashCode()方法和equals()方法
    1. HashMap刚创建时,table是null,为了节省空间,当添加第一个元素时,table容量调整为16
    2. 当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容后大小为原来的2倍,目的是减少调整元素的个数
    3. jdk 1.8 当每个链表长度大于8,并且数组元素个数大于等于64时,会调整成红黑树,目的提高执行效率
    4. jdk 1.8 当量表长度小于6时,调整成链表
    5. jdkv 1.8以前 链表是头插入,jdk1.8以后是尾插入
        static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;//初始容量大小
        static final int MAXIMUM_CAPACITY = 1 << 30;//数组最大容量
        static final float DEFAULT_LOAD_FACTOR = 0.75f;//默认加载因子
        static final int TREEIFY_THRESHOLD = 8;//JDK1.8 当链表长度大于8时,调整为红黑树
        static final int UNTREEIFY_THRESHOLD = 6;//jdk1.8 当链表长度小于6,调整成链表
        static final int MIN_TREEIFY_CAPACITY = 64;//jdk1.8 当链表长度大于8时,并且集合元素个数大于64,调整成红黑树
        transient Node<K,V>[] table;//哈希表中的数组
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    Hashtable

    在这里插入图片描述
    Properties

    TreeMap

    实现了SortedMap接口(是Map的子接口),可以对key自动排序
    存储接口:红黑树
    如果key是实体类,那么该类需要实现Comparable接口,重写CompareTo方法

    Collections 工具类

    public class Test26 {
        public static void main(String[] args) {
            ArrayList<Integer> integers = new ArrayList<>();
            integers.add(12);
            integers.add(1);
            integers.add(13);
            //排序
            Collections.sort(integers);
            System.out.println(integers);
            //binarySearch二分查找,找到了返回其所在的索引,否则返回一个小于0的数
            int i = Collections.binarySearch(integers, 12);
            int j = Collections.binarySearch(integers, 2);
            System.out.println(i+":"+j);
            //Copy复制
            ArrayList<Integer> dest = new ArrayList<>();
            //必须集合大小一致
            for (Integer integer : integers) {
                dest.add(0);
            }
            Collections.copy(dest,integers);
            System.out.println(dest.toString());
            //翻转排序
            Collections.reverse(dest);
            System.out.println(dest);
            //打乱顺序
            Collections.shuffle(dest);
            System.out.println(dest);
    
            //list转数组
            Integer[] ts = dest.toArray(new Integer[dest.size()]);
            System.out.println(Arrays.toString(ts));
    
            //数组转list,但是是一个受限集合,不能使用list方法
            List<Integer> integers1 = Arrays.asList(ts);
            //integers1.add(2);
            System.out.println(integers1);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    泛型

    • Java泛型是JDK1.5引入的一个新特性,其本质是参数化类型,把类型作为参数传递
    • 常见形式泛型类泛型接口泛型方法
    • 语法 : <T,…> T称为类型占位符,表示一种引用类型
    • 好处:
    1. 提高代码的重用性
    2. 防止类型转换异常,提高代码的安全性

    泛型类

    集合工具类,定义了除了存取以外的集合常用方法
    在这里插入图片描述

    /**
     * 泛型类
     * @param <T>
     */
    public class Test19<T> {
        //创建变量
        T t;
    
        //泛型作为方法参数
        public void show(T t){
            System.out.println(t);
        }
        //泛型作为方法返回值
        public T getT(){
            return t;
        }
    
        public static void main(String[] args) {
            //泛型只能使用引用类型,不同泛型对象不能相互复制
            Test19<String> stringTest19 = new Test19<>();
            stringTest19.t="cxc";
            stringTest19.show("cx");
            System.out.println(stringTest19.getT());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    泛型接口

    /**
     * 泛型接口
     * 不能泛型静态常量
     * @param <T>
     */
    public interface Generics<T> {
        String name="cx";
        //T t;错误
        T fun(T t);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    package com.utils;
    
    public class GenericsImpl<S> implements Generics<String>{
        @Override
        public String fun(String s) {
            System.out.println(s);
            return s;
        }
    }
    
    class GenericsImpl2<T> implements Generics<T>{
        @Override
        public T fun(T t) {
            System.out.println(t);
            return t;
        }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    package com.utils;
    
    public class Test20 {
        public static void main(String[] args) {
            GenericsImpl<String> generics = new GenericsImpl<String>();
            generics.fun("cx");
    
            GenericsImpl2<Integer> integerGenericsImpl2 = new GenericsImpl2<>();
            integerGenericsImpl2.fun(1);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    泛型方法

    
    /**
     * 泛型方法
     * 语法: <T> 返回值类型
     */
    public class MyGenerics {
    
        //泛型方法
        public <T> T show(T t){
            System.out.println(t);
            return t;
        }
    
        public static void main(String[] args) {
            MyGenerics myGenerics = new MyGenerics();
            myGenerics.show("cx");
            myGenerics.show(12);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    泛型集合

    • 概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致
    • 特点:
    1. 编译时即可检查,而非运行时抛出异常
    2. 访问时,不必类型转换
    3. 不同泛型之间引用不能相互赋值,泛型不存在多态
  • 相关阅读:
    文字转语音:语音合成(Speech Synthesis) 数组文字循环播放
    根据模板动态生成word(三)使用poi-tl生成word
    非零基础自学Java (老师:韩顺平) 第8章 面向对象编程(中级部分) 8.5 访问修饰符
    Node.js 实战 第2章 Node 编程基础 2.3 用module.exports 微调模块的创建
    SpringMVC ---- @RequestMapping注解
    Spring的三种注入方式(为什么推荐构造器注入?)
    C/C++数据结构之深入了解树与二叉树:概念、存储结构和遍历
    Auto.js脚本程序打包
    基于Django与深度学习的股票预测系统 计算机竞赛
    OpenGL ES之深入解析RGB图像与YUV格式之间的相互转换
  • 原文地址:https://blog.csdn.net/m0_56981185/article/details/124656631