目录

一、为什么要引用集合类?

     数组的特点:

     集合的特点:

二、集合类体系结构:

三、Collection集合体系:

四、Collection常用API:

五、遍历方式:

        迭代器:

        foreach/增强for循环:

        Lambda表达式:

六、List系列集合:

        List系列集合特点:

        List集合特有方法:

        ArrayList集合底层原理:

        LinkedList的特点:

        LinkedList集合特有功能:

七、Set系列集合:

        Set系列集合特点:

        Set集合实现类特点:

        HashSet元素无序、去重复的底层原理:哈希表

        LinkedHashSet集合概述和特点:

        TreeSet集合概述和特点:

        TreeSet集合默认的规则:

        自定义排序规则:

八、总结:


一、为什么要引用集合类?

       提到集合类都会想到数组,集合和数组都是容器。

     数组的特点:

        1、数组的类型确定,长度固定。

        2、在进行增删该改查操作时,需要放弃原有数组或者移位,所以数组不太适合。

     集合的特点:

        1、集合的大小不固定,可以动态变化,类型也可以选择不固定。

        2、集合非常适合元素的增删改查。

     注意:集合只能存储引用类数据,如果想要存储基本数据类型可以选用包装类。

二、集合类体系结构:

  •  Collection单列集合:每个元素(数据)只包含一个值。
  •           Map双列集合:每个元素包含两个值。

       注意:今天先总结Collection系列集合。

三、Collection集合体系:

java 修改集合元素位置_java

四、Collection常用API:

package com.jiazhong.Aggregate.Collection.Collection_api;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

/*

*/
public class Collection_api {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();
        //1、添加元素,添加成功返回true
        list.add("Java");
        list.add("Java");
        list.add("HTML");
        System.out.println(list.add("MySQL"));
        list.add("Python");
        System.out.println(list);

        //2、清空集合的元素
     //   list.clear();
     //   System.out.println(list);

        //3、判断集合是否为空,空返回true,反之false
       // System.out.println(list.isEmpty());

        //4、获取集合的大小
        System.out.println(list.size());

        //5、判断集合中是否包含某个元素
        System.out.println(list.contains("Java"));
        System.out.println(list.contains("java"));

        //6、删除某个元素:如果有多个重复元素默认删除第一个
        list.remove("Java");
        System.out.println(list);

        //7、把集合转换成数组
        Object[] o = list.toArray();
        System.out.println("数组:"+ Arrays.toString(o));

        System.out.println("---------拓展---------");
        Collection<String> c1 = new ArrayList<>();
        c1.add("java");
        c1.add("Java");
        Collection<String> c2 = new ArrayList<>();
        c2.add("张三");
        c2.add("你好");

        c2.addAll(c1);
        System.out.println(c1);
        System.out.println(c2);
    }
}

五、遍历方式:

        迭代器:

package com.jiazhong.Aggregate.Collection.Collection_traversal;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/*
    迭代器
*/
public class CollectionDemo01 {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();
        list.add("杨港");
        list.add("张三");
        list.add("李四");
        list.add("王五");

        System.out.println(list);

        //1、得到当前集合的迭代器对象
        Iterator<String> it = list.iterator();
//        String e = it.next();
//        System.out.println(e);
//        System.out.println(it.next());
//        System.out.println(it.next());
//        System.out.println(it.next());

//        System.out.println(it.next());//NoSuchElementException

        //2、定义while循环
        while (it.hasNext()){
            String e = it.next();
            System.out.println(e);
        }
    }
}

        foreach/增强for循环:

package com.jiazhong.Aggregate.Collection.Collection_traversal;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

/*
    foreach/增强for循环
 */
public class CollectionDemo02 {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();
        list.add("杨港");
        list.add("张三");
        list.add("李四");
        list.add("王五");

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

        double[] score = {11.1,45.5,60.5,59.5};
        for (double ele : score) {
            System.out.println(ele);
        }
    }
}

        Lambda表达式:

package com.jiazhong.Aggregate.Collection.Collection_traversal;

import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;

/*
    Lambda表达式
*/
public class CollectionDemo03 {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<>();
        list.add("杨港");
        list.add("张三");
        list.add("李四");
        list.add("王五");

//        list.forEach(new Consumer<String>() {
//            @Override
//            public void accept(String s) {
//                System.out.println(s);
//            }
//        });

        list.forEach( s-> {
                System.out.println(s);
        });
    }
}

六、List系列集合:

        List系列集合特点:

  • ArrayList、LinkedList : 有序、可重复、有索引。
  • 有序:存储和取出的元素顺序一致。
  • 可重复:存储的元素可以重复。
  • 有索引:可以通过索引操作元素。

        List集合特有方法:

package com.jiazhong.Aggregate.Collection.Collection_list;

import java.util.ArrayList;
import java.util.List;

public class ListDemo01 {
    public static void main(String[] args) {
        // 1.创建一个ArrayList集合对象:
        // List:有序,可重复,有索引的。
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("Java");
        list.add("Html");
        list.add("Web");

        // 2.在某个索引位置插入元素。
        list.add(2,"你好");
        System.out.println(list);
        // 3.根据索引删除元素,返回被删除元素
        System.out.println(list.remove(2));
        System.out.println(list);
        // 4.根据索引获取元素:public E get(int index):返回集合中指定位置的元素。
        System.out.println(list.get(2));
        // 5.修改索引位置处的元素: public E set(int index, E element)
        System.out.println(list.set(1, "高斯林"));
        System.out.println(list);
    }
}

        ArrayList集合底层原理:

        ArrayList底层是基于数组实现的:根据索引定位元素快,增删需要做元素的移位操作。

        第一次创建集合并添加第一个元素时,在底层创建一个默认长度为10的数组。

        LinkedList的特点:

        底层数据结构是双链表,查询慢,首尾操作速度是极快的,所以有很多首尾特有的API。

        LinkedList集合特有功能:

        

package com.jiazhong.Aggregate.Collection.Collection_list;

import java.util.LinkedList;

public class ListDemo03 {
    public static void main(String[] args) {
         //LinkedList 可以完成队列结构,和栈结构(双向链表)
        //栈
        LinkedList<String> stack = new LinkedList<>();
        //压栈 入栈
        stack.push("第一颗子弹");
        stack.addFirst("第二颗子弹");
        stack.addFirst("第三颗子弹");
        stack.addFirst("第四颗子弹");
        //出栈 弹栈
        stack.pop();
        stack.removeFirst();
        stack.removeFirst();
        System.out.println(stack);

        //队列

        LinkedList<String> queue = new LinkedList<>();
        //入队
        queue.addLast("1号");
        queue.addLast("2号");
        queue.addLast("3号");
        queue.addLast("4号");
        System.out.println(queue);
        queue.removeFirst();
        queue.removeFirst();
        queue.removeFirst();
        System.out.println(queue);
    }
}

七、Set系列集合:

        Set系列集合特点:

  •         无序:存取顺序不一致
  •         不重复:可以去除重复
  •         无索引:没有带索引的方法,所以不能使用普通for循环遍历,也不能通过索引来获取元                        素。

        Set集合实现类特点:

  •        HashSet:无序、不重复、无索引
  •        LinkedHashSet: 有序、不重复、无索引
  •        TreeSet:排序、不重复、无索引

        Set集合的功能基本上与Collection的API一致。

package com.itheima.d1_set;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;

public class SetDemo1 {
    public static void main(String[] args) {
        Set<String> sets = new HashSet<>();//无序,不重复,无索引
        sets.add("MySQL");
        sets.add("Java");
        sets.add("Java");
        sets.add("HTML");
        sets.add("HTML");
        sets.add("StringBoot");
        System.out.println(sets);

        Set<String> set = new LinkedHashSet<>();//有序,不重复,无索引
        set.add("MySQL");
        set.add("Java");
        set.add("Java");
        set.add("HTML");
        set.add("HTML");
        set.add("StringBoot");
        System.out.println(set);

        Set<Integer> sett = new TreeSet<>();//排序,不重复,无索引
        sett.add(23);
        sett.add(11);
        sett.add(5);
        sett.add(24);
        sett.add(31);
        sett.add(10);
        System.out.println(sett);
    }
}

结果:[Java, StringBoot, MySQL, HTML]
[MySQL, Java, HTML, StringBoot]
[5, 10, 11, 23, 24, 31]

        HashSet元素无序、去重复的底层原理:哈希表

        哈希表的组成:JDK8之前使用数组+链表组成

                                  JDK8开始采用数组+链表+红黑树组成

        对象的哈希值特点:同一对象多次调用hashCode()方法返回的哈希值是相同的。

                                         默认情况下,不同对象的哈希值是不同的。

        哈希表的详细流程:

                1、创建一个默认长度为16,默认加载0.75的数组

                2、根据元素的哈希值和数组的长度求出应存入的位置(哈希值/16的余数即位置)

                3、判断当前位置是否为null,不为null直接存入。若为null表示该位置有元素,则调用equals方法比较属性值

                4、当数组存满到16*0.75=12时,则扩容,扩容到原来的两倍

        LinkedHashSet集合概述和特点:

        有序、不重复、无索引

        这里的有序指的是保证存储和取出的元素顺序一致

        原理:底层数据结构依然是哈希表,只不过每个元素又额外多了一个双链表的机制记录存储的顺序。

        TreeSet集合概述和特点:

        可排序、不重复、无索引

        可排序:按照元素的大小默认升序(由小到大)排序。

        TreeSet集合底层是基于红黑树的数据结构实现排序的,增删改查性能都较好。

        TreeSet集合默认的规则:

        对于数值类型:按照大小进行升序排序。

        对于字符串类型:默认按照首字母的编号升序排序。

        对于自定义的Student对象,无法直接排序。

结论:想要使用TreeSet存储自定义类型,需要指定排序规则。        

        自定义排序规则:

Comparable接口重写里面的compareTo方法来制定比较规则。

        

package com.itheima.d1_set;

public class Student implements Comparable<Student>{
    private String name;
    private int age;
    private char sex;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public char getSex() {
        return sex;
    }

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

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

    public void setSex(char sex) {
        this.sex = sex;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Student student = (Student) o;

        if (age != student.age) return false;
        if (sex != student.sex) return false;
        return name != null ? name.equals(student.name) : student.name == null;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        result = 31 * result + (int) sex;
        return result;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex=" + sex +
                '}';
    }
/*
 方法一:实现Comparable接口重写里面的compareTo方法来制定比较规则。
 */
    @Override
    public int compareTo(Student student) {
        return this.age-student.age;
    }
}

   

package com.itheima.d1_set;

import java.util.Set;
import java.util.TreeSet;

public class SetDemo5 {
    public static void main(String[] args) {
        Set<Student> s = new TreeSet<>();
        s.add(new Student("杨港",21,'男'));
        s.add(new Student("张三",20,'女'));
        s.add(new Student("李四",25,'男'));
        System.out.println(s);
    }
}

结果:[Student{name='张三', age=20, sex=女}, Student{name='杨港', age=21, sex=男}, Student{name='李四', age=25, sex=男}]

TreeSet集合有参构造器,可以设置Comparator接口对应的比较器对象,来制定比较规则。

                

package com.itheima.d1_set;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class SetDemo6 {
    public static void main(String[] args) {
        Set<Student> s = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student student, Student t1) {
                return t1.getAge()-student.getAge();
            }
        });
        s.add(new Student("杨港", 21, '男'));
        s.add(new Student("张三", 20, '女'));
        s.add(new Student("李四", 25, '男'));
        System.out.println(s);
    }
}


结果:[Student{name='李四', age=25, sex=男}, Student{name='杨港', age=21, sex=男}, Student{name='张三', age=20, sex=女}]

八、总结:

        1、如果希望元素可以重复,又有索引,索引查询要快。

                用ArrayList集合,基于数组的。

        2、如果希望元素可以重复,又有索引,增删首尾要快。

                用LinkedList集合,基于链表的。

        3、如果希望元素增删改查都快,但元素不重复、无序、无索引。

                用HashSet集合,基于哈希表的。

        4、如果希望元素增删改查都快,但元素不重复、有序、无索引。

                用LinkedHashSet集合,基于哈希表和双链表。

        5、如果要对希望元素排序。

                用TreeSet集合,基于红黑树。