List集合、Set集合、Collections类、java数据结构、集合框架【学习笔记】

一、数据结构
1.栈结构
特点:先进后出
栈内存:先进后出。主方法最先压栈,剩余的方法随着调用就会不断的进栈。当执行完毕时,立即从栈内存消失
堆内存:当new对象的时候,对象才出现。当这个对象没有任何引用的时候,会变成垃圾。由垃圾回收器不定时的回收
栈结构只能操作一端,不是运算受限的线性表

2.队列结构
    特点:先进先出
    举例:排队
    运算受限的线性表
    能对首尾进行操作
    LinkedList中的addFrist()和addLast()可以模拟出队列

3.数组结构
    特点:
        查询快:数组是一块连续的内存空间。而且有对应的索引。通过索引快速的定位到要查找的内容
        增删慢:数组的长度是固定的,如果要对元素进行增删。则需要创建新数组来完成

4.链表结构
    数据结构层面特点:
        查询慢:链表的地址不是连续的,查询的时候需要一个一个的进行查找
        增删快:每个元素都会记录上一个元素的地址值(双向的是互相记录地址)。如果想删除或增加一个元素,其他的元素不需要变动,只需要将对应的记录更改即可
    LinkedList集合:
        此集合也是有索引的。有索引但是查询慢的原因如下:
        我们传入一个要查询的索引,底层先会做一个判断。
         结果1:如果传入的索引要是比集合长度的中间值索引要小,从前向后查找。而且是一个一个的找
         结果2:如果传入的索引要是比集合长度的中间值索引要大,从后向前查找。而且是一个一个的找

    总结:
        如果查询多,优先使用ArrayList
        如果增删多,优先使用LinkedList
        如果不确定,优先使用ArrayList

5.树结构
    图解略~

二、List
1.List特点
有索引、可以存储重复元素、存取有序
ArrayList:底层是数组实现,查询快、增删慢。
|–ArrayList集合底层是数组结构,第一个数组是长度为10,如果添加的元素超过10,那么下一个就会
以1.5倍的速度去创建一个新的集合,再使用Arrays.copyOfRange(Object []original,start,end) 不包含end

               /*
                    //这就属于多态   只能用List接口里面的方法
                    List<String> list = new ArrayList<>();
                    //欲想使用ArrayList集合中的trimToSzie()方法,那么就不许转型    
                    // 这仅仅是为了演示一下多态的转型概念
                    ArrayList<String> arr = (ArrayList<String>) list;
                    arr.trimToSize();   //这时候就可以使用这个方法了
               */
    LinkedList:底层是链表实现,查询慢、增删快。
        |--可以对首尾进行操作(添加或者删除操作)比add(int index,E element) 和 remove(int index)
           方法的效率要稍微高那么一点点,因为他在进行添加删除操作的时候不用去通过下标去查找
2.常用方法
    void add(int index,E e);         向集合中指定索引位置去添加元素
    E get(int index);                获取指定索引处的元素
    E remove(int index);             删除指定索引上的元素
    E set(int index,E e);        修改指定索引上的元素
3.示例代码:
public class Demo01List {
            public static void main(String[] args) {
                //创建一个List集合对象,多态
                List<String> list = new ArrayList<>();
                //使用add方法往集合中添加元素
                list.add("a");
                list.add("b");
                list.add("c");
                list.add("d");
                list.add("a");
                //打印集合
                System.out.println(list);//[a, b, c, d, a]  不是地址重写了toString

                //public void add(int index, E element): 将指定的元素,添加到该集合中的指定位置上。
                //在c和d之间添加一个itheima
                list.add(3,"itheima");//[a, b, c, itheima, d, a]
                System.out.println(list);

                //public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。
                //移除元素
                String removeE = list.remove(2);
                System.out.println("被移除的元素:"+removeE);//被移除的元素:c
                System.out.println(list);//[a, b, itheima, d, a]

                //public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
                //把最后一个a,替换为A
                String setE = list.set(4, "A");
                System.out.println("被替换的元素:"+setE);//被替换的元素:a
                System.out.println(list);//[a, b, itheima, d, A]
            }
        }
4.LinkedList集合
        特有方法:
            java.util.LinkedList集合 implements List接口
            LinkedList集合的特点:
                1.底层是一个链表结构:查询慢,增删快
                2.里边包含了大量操作首尾元素的方法
                注意:使用LinkedList集合特有的方法,不能使用多态

                void addFirst(E e):将指定元素插入此列表的开头。
                void addLast(E e):将指定元素添加到此列表的结尾。
                void push(E e):将元素推入此列表所表示的堆栈。

                E getFirst():返回此列表的第一个元素。
                E getLast():返回此列表的最后一个元素。

                E removeFirst():移除并返回此列表的第一个元素。
                E removeLast():移除并返回此列表的最后一个元素。
                E pop():从此列表所表示的堆栈处弹出一个元素。

                boolean isEmpty():如果列表不包含元素,则返回truepublic class Demo02LinkedList {
            public static void main(String[] args) {
                show03();
            }

            /*
                - public E removeFirst():移除并返回此列表的第一个元素。
                - public E removeLast():移除并返回此列表的最后一个元素。
                - public E pop():从此列表所表示的堆栈处弹出一个元素。此方法相当于 removeFirst
             */
            private static void show03() {
                //创建LinkedList集合对象
                LinkedList<String> linked = new LinkedList<>();
                //使用add方法往集合中添加元素
                linked.add("a");
                linked.add("b");
                linked.add("c");
                System.out.println(linked);//[a, b, c]

                //String first = linked.removeFirst();
                String first = linked.pop();
                System.out.println("被移除的第一个元素:"+first);
                String last = linked.removeLast();
                System.out.println("被移除的最后一个元素:"+last);
                System.out.println(linked);//[b]
            }

            /*
                - public E getFirst():返回此列表的第一个元素。
                - public E getLast():返回此列表的最后一个元素。
             */
            private static void show02() {
                //创建LinkedList集合对象
                LinkedList<String> linked = new LinkedList<>();
                //使用add方法往集合中添加元素
                linked.add("a");
                linked.add("b");
                linked.add("c");

                //linked.clear();//清空集合中的元素 在获取集合中的元素会抛出NoSuchElementException

                //public boolean isEmpty():如果列表不包含元素,则返回true。
                if(!linked.isEmpty()){
                    String first = linked.getFirst();
                    System.out.println(first);//a
                    String last = linked.getLast();
                    System.out.println(last);//c
                }
            }

            /*
                - public void addFirst(E e):将指定元素插入此列表的开头。
                - public void addLast(E e):将指定元素添加到此列表的结尾。
                - public void push(E e):将元素推入此列表所表示的堆栈。此方法等效于 addFirst(E)。
             */
            private static void show01() {
                //创建LinkedList集合对象
                LinkedList<String> linked = new LinkedList<>();
                //使用add方法往集合中添加元素
                linked.add("a");
                linked.add("b");
                linked.add("c");
                System.out.println(linked);//[a, b, c]

                //public void addFirst(E e):将指定元素插入此列表的开头。
                //linked.addFirst("www");
                linked.push("www");
                System.out.println(linked);//[www, a, b, c]

                //public void addLast(E e):将指定元素添加到此列表的结尾。此方法等效于 add()
                linked.addLast("com");
                System.out.println(linked);//[www, a, b, c, com]
            }
        }
5.Vector集合
    ArrayList和Vector集合的区别
        相同点:底层都是数组实现的
        不同点:ArrayList是JDK1.2版本出现的。Vector是JDK1.0版本出现的
                ArrayList是线程不安全的,效率较高,但是数据不安全
                Vector是线程安全的,效率较低,但是数据安全
    示例代码:
    public class Demo01 {
                public static void main(String[] args) {
                    Vector<String> v = new Vector<>();
                    v.addElement("abc");
                    v.addElement("bcd");
                    v.addElement("def");

                    for (String s : v) {
                        System.out.println(s);
                    }

                    System.out.println("================");

                    Iterator<String> it = v.iterator();
                    while(it.hasNext()) {
                        System.out.println(it.next());
                    }

                    System.out.println("================");

                    Enumeration<String> e = v.elements();
                    while(e.hasMoreElements()) {
                        System.out.println(e.nextElement());
                    }

                }
            }

三、Set
1.Set集合特点
无索引、不能存储重复元素、存取无序
HashSet:底层是哈希算法(红黑树),无索引、不能存储重复元素、存取无序
LinkedHashSet:底层是哈希算法+链表双实现,无索引、不能存储重复元素。可以保证存取顺序
|–LinkedHashSet是有序的

    注意事项:
    ???Set集合遍历的时候不能使用for循环(因为没有下标,无法对其遍历)
        |--增强for循环
        |--迭代器

    ???红黑树(平衡二叉树/排序树)查询速度相当快  -->桶结构存储
2.示例代码:
public class Demo01Set {
            public static void main(String[] args) {
                Set<Integer> set = new HashSet<>();
                //使用add方法往集合中添加元素
                set.add(1);
                set.add(3);
                set.add(2);
                set.add(1);
                //使用迭代器遍历set集合
                Iterator<Integer> it = set.iterator();
                while (it.hasNext()){
                    Integer n = it.next();
                    System.out.println(n);//1,2,3    无序,没有重复的
                }
                //使用增强for遍历set集合
                System.out.println("-----------------");
                for (Integer i : set) {
                    System.out.println(i);
                }
            }
        }
3.Set集合不重复的原理
    第一种情况:哈希值不同,直接存储
    第二种情况:哈希值相同,但是equals方法不同。以桶结构存储
    第三种情况:哈希值相同,但是equals方法也相同。不存储了

4.HashSet存储自定义类型数据
    此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。
    它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。
    //Person类
        public class Person {
            private String name;
            private int age;

            public Person() {
            }

            public Person(String name, int age) {
                this.name = name;
                this.age = age;
            }

            @Override
            public boolean equals(Object o) {
                if (this == o) return true;
                if (o == null || getClass() != o.getClass()) return false;
                Person person = (Person) o;
                return age == person.age &&
                        Objects.equals(name, person.name);
            }

            @Override
            public int hashCode() {
                return Objects.hash(name, age);
            }

            @Override
            public String toString() {
                return "Person{" +
                        "name='" + name + '\'' +
                        ", age=" + age +
                        '}';
            }

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            public int getAge() {
                return age;
            }

            public void setAge(int age) {
                this.age = age;
            }
        }


        //测试类
        public class Demo03HashSetSavePerson {
            public static void main(String[] args) {
                //创建HashSet集合存储Person
                HashSet<Person> set = new HashSet<>();
                Person p1 = new Person("小美女",18);
                Person p2 = new Person("小美女",18);
                Person p3 = new Person("小美女",19);

                set.add(p1);
                set.add(p2);
                set.add(p3);

                System.out.println(set);
            }
        }
5.LinkedHashSet集合的使用
    public class Demo04LinkedHashSet {
            public static void main(String[] args) {
                HashSet<String> set = new HashSet<>();
                set.add("www");
                set.add("abc");
                set.add("abc");
                set.add("itcast");
                System.out.println(set);//[abc, www, itcast] 无序,不允许重复

                LinkedHashSet<String> linked = new LinkedHashSet<>();
                linked.add("www");
                linked.add("abc");
                linked.add("abc");
                linked.add("itcast");
                System.out.println(linked);//[www, abc, itcast] 有序,不允许重复
            }
        }

四、可变参数
1.定义格式
数据类型…变量名

2.注意事项
    一个方法的参数中只能有一个可变参数
    如果有多个参数,可变参数必须放在最后一个

3.示例代码
        public class Demo01VarArgs {
            public static void main(String[] args) {
                //int i = add();
                //int i = add(10);
                int i = add(10,20);
                //int i = add(10,20,30,40,50,60,70,80,90,100);
                System.out.println(i);

                method("abc",5.5,10,1,2,3,4);
            }

            /*
                可变参数的注意事项
                    1.一个方法的参数列表,只能有一个可变参数
                    2.如果方法的参数有多个,那么可变参数必须写在参数列表的末尾
             */
            /*public static void method(int...a,String...b){

            }*/

            /*public static void method(String b,double c,int d,int...a){
            }*/

            //可变参数的特殊(终极)写法
            public static void method(Object...obj){

            }

            /*
                定义计算(0-n)整数和的方法
                已知:计算整数的和,数据类型已经确定int
                但是参数的个数不确定,不知道要计算几个整数的和,就可以使用可变参数
                add(); 就会创建一个长度为0的数组, new int[0]
                add(10); 就会创建一个长度为1的数组,存储传递来过的参数 new int[]{10};
                add(10,20); 就会创建一个长度为2的数组,存储传递来过的参数 new int[]{10,20};
                add(10,20,30,40,50,60,70,80,90,100); 就会创建一个长度为2的数组,存储传递来过的参数 new int[]{10,20,30,40,50,60,70,80,90,100};
             */
            public static int add(int...arr){
                //System.out.println(arr);//[I@2ac1fdc4 底层是一个数组
                //System.out.println(arr.length);//0,1,2,10
                //定义一个初始化的变量,记录累加求和
                int sum = 0;
                //遍历数组,获取数组中的每一个元素
                for (int i : arr) {
                    //累加求和
                    sum += i;
                }
                //把求和结果返回
                return sum;
            }
        }

五、集合的工具类
1.Collections工具类
- public static boolean addAll(Collection c, T… elements):往集合中添加一些元素。
- public static void shuffle(List

            public class Demo01Collections {
                public static void main(String[] args) {
                    ArrayList<String> list = new ArrayList<>();

                    //public static <T> boolean addAll(Collection<T> c, T... elements):往集合中添加一些元素。
                    Collections.addAll(list,"a","b","c","d","e");

                    System.out.println(list);//[a, b, c, d, e]

                    //public static void shuffle(List<?> list) 打乱顺序:打乱集合顺序。
                    Collections.shuffle(list);
                    System.out.println(list);//[b, d, c, a, e], [b, d, c, a, e]
                }
            }
    - public static <T> void sort(List<T> list):将集合中元素按照默认规则排序。
    示例代码:
    //Person类
            public class Person implements Comparable<Person>{
                private String name;
                private int age;

                public Person() {
                }

                public Person(String name, int age) {
                    this.name = name;
                    this.age = age;
                }

                @Override
                public String toString() {
                    return "Person{" +
                            "name='" + name + '\'' +
                            ", age=" + age +
                            '}';
                }

                public String getName() {
                    return name;
                }

                public void setName(String name) {
                    this.name = name;
                }

                public int getAge() {
                    return age;
                }

                public void setAge(int age) {
                    this.age = age;
                }

                //重写排序的规则
                @Override
                public int compareTo(Person o) {
                    //return 0;//认为元素都是相同的
                    //自定义比较的规则,比较两个人的年龄(this,参数Person)
                    //return this.getAge() - o.getAge();//年龄升序排序
                    return o.getAge() - this.getAge();//年龄降序排序
                }
            }

            //测试类
            public class Demo02Sort {
                public static void main(String[] args) {
                    ArrayList<Integer> list01 = new ArrayList<>();
                    list01.add(1);
                    list01.add(3);
                    list01.add(2);
                    System.out.println(list01);//[1, 3, 2]

                    //public static <T> void sort(List<T> list):将集合中元素按照默认规则排序。
                    Collections.sort(list01);//默认是升序

                    System.out.println(list01);//[1, 2, 3]

                    ArrayList<String> list02 = new ArrayList<>();
                    list02.add("a");
                    list02.add("c");
                    list02.add("b");
                    System.out.println(list02);//[a, c, b]

                    Collections.sort(list02);
                    System.out.println(list02);//[a, b, c]

                    ArrayList<Person> list03 = new ArrayList<>();
                    list03.add(new Person("张三",18));
                    list03.add(new Person("李四",20));
                    list03.add(new Person("王五",15));
                    System.out.println(list03);//[Person{name='张三', age=18}, Person{name='李四', age=20}, Person{name='王五', age=15}]

                    Collections.sort(list03);
                    System.out.println(list03);
                }
            }
    - public static <T> void sort(List<T> list,Comparator<? super T> ):将集合中元素按照指定规则排序。
    示例代码:
        //学生类
            public class Student {
                private String name;
                private int age;
                private int score;

                public Student() {
                }

                public Student(String name, int age, int score) {
                    this.name = name;
                    this.age = age;
                    this.score = score;
                }

                public String getName() {
                    return name;
                }

                public void setName(String name) {
                    this.name = name;
                }

                public int getAge() {
                    return age;
                }

                public void setAge(int age) {
                    this.age = age;
                }

                public int getScore() {
                    return score;
                }

                public void setScore(int score) {
                    this.score = score;
                }

                @Override
                public String toString() {
                    return "Student{" +
                            "name='" + name + '\'' +
                            ", age=" + age +
                            ", score=" + score +
                            '}';
                }
            }

            //测试类
            public class Test02 {
                public static void main(String[] args) {
                    ArrayList<Student> list = new ArrayList<>();

                    Student s1 = new Student("张三",23,88);
                    Student s2 = new Student("李四",22,85);
                    Student s3 = new Student("王五",25,95);
                    Student s4 = new Student("赵六",22,87);

                    list.add(s1);
                    list.add(s2);
                    list.add(s3);
                    list.add(s4);

                    System.out.println(list);

                    //按照年龄的升序为主要条件
                    //如果年龄一样的情况,再按照成绩的降序排序
                    Collections.sort(list, new Comparator<Student>() {
                        @Override
                        public int compare(Student s1, Student s2) {
                            int result = s1.getAge() - s2.getAge(); // 按照年龄的升序排序
                            //如果年龄相同,再按照成绩的降序排序
                            return (result == 0) ? s2.getScore() - s1.getScore() : result;
                        }
                    });



                    //按照年龄的升序排序
                    // [Student{name='李四', age=22, score=85}, Student{name='赵六', age=22, score=87}, Student{name='张三', age=23, score=88}, Student{name='王五', age=25, score=95}]
                    /*Collections.sort(list, new Comparator<Student>() {
                        @Override
                        public int compare(Student s1, Student s2) {
                            int result = s1.getAge() - s2.getAge();
                            return result;
                        }
                    });*/

                    System.out.println(list);
                }
            }

            补充:
                /*下面我想对一个ArrayList集合进行降序排序(本来默认的都是升序排序)*/
                    ArrayList<Integer> list =  new ArrayList<>();
                    list.add(1);
                    list.add(5);
                    list.add(3);
                    list.add(7);
                    list.add(4);
                    Collections.sort(list, new Comparator<Integer>() {
                        @Override
                        public int compare(Integer o1, Integer o2) {
                            return o2 - o1;    //重写之后的方法进行的是降序排序
                        }
                    });
                    System.out.println(list);
2.补充的工具类方法
    public class Demo04 {
            public static void main(String[] args) {
                ArrayList<String> list = new ArrayList<>();
                list.add("aa");
                list.add("bb");
                list.add("cc");
                list.add("dd");
                list.add("ee");


                //int binarySearch(List list, T key)    使用二分查找法获取元素在集合中出现的索引位置   如果查找的元素不存在,则返回此元素的-插入点-1
                int index = Collections.binarySearch(list,"cc");
                System.out.println(index);

                //boolean replaceAll(List<T> list, T oldVal, T newVal)   使用新元素对集合中的老元素进行替换
                Collections.replaceAll(list,"dd","kk");
                System.out.println(list);

                //void reverse(List<?> list)            反转集合
                Collections.reverse(list);

                System.out.println(list);

                //void swap(List<?> list, int i, int j) 将两个索引位置上的元素交换
                Collections.swap(list,0,1);

                System.out.println(list);


                //void copy(List dest, List src)        将源集合复制到目标集合中.目标集合长度必须大于等于源集合的长度
               /* ArrayList<String> dest = new ArrayList<>();
                dest.add("a");
                dest.add("b");
                dest.add("c");
                dest.add("d");
                dest.add("e");
                dest.add("f");

                Collections.copy(dest,list);

                System.out.println(dest);*/
            }
        }

猜你喜欢

转载自blog.csdn.net/jmj18756235518/article/details/81160632