【Java】Collection集合

集合

        集合和数组都是容器

数组的特点:

        数组定义完成并启动后,类型确定、长度固定

        适合元素的个数和类型确定的业务场景,不适合做需要增删数据操作

集合的特点:

        集合大小不固定,启动后可以动态变化类型也可以选择不固定

        集合非常适合做元素的增删操作

1.数组和集合的元素存储的个数
        数组定义后类型确定长度固定
        集合类型可以不固定大小是可变的


2.数组和集合存储元素的类型问题
        数组可以存储基本类型引用类型的数据
        集合只能存储引用数据类型的数据


3.数组和集合适合的场景
        数组适合做数据个数和类型确定的场景
        集合适合做数据个数不确定,且要做增删元素的场景

集合类体系结构

🐼Collection:单列集合,每个元素包含个值

🐼Map:         双列集合,每个元素包含个值(键值对)

Collection集合体系

Collection集合特点:

        List系列集合:添加的元素是有序可重复有索引
                ArrayList:有序、可重复、有索引

                LinekdList :有序、可重复、有索引


        Set系列集合:添加的元素是无序不重复无索引
                HashSet: 无序、不重复、无索引

                        LinkedHashSet: 有序、不重复、无索引
                TreeSet:
按照大小默认升序排序、不重复、无索引

集合对于泛型的支持:

        集合都是支持泛型的,可以在编译阶段约束集合只能操作某种数据类型

Collection<String> lists = new ArrayList<String>();
Collection<String> lists = new ArrayList<>(); // JDK 1.7开始后面的泛型类型申明可以省略不写

集合中要存储基本类型的数据,就要使用包装类

// 存储基本类型使用包装类
Collection<Integer> lists = new ArrayList<>();
Collection<Double> lists = new ArrayList<>();

1.集合的代表是?
        Collection接口

2.Collection集合分了哪2大常用的集合体系?
        List系列集合:添加的元素是有序可重复有索引
        Set系列集合:添加的元素是无序不重复无索引

3.如何约定集合存储数据的类型,需要注意什么?
        集合支持泛型
        集合和泛型不支持基本类型,只支持引用数据类型

Collection集合常用API

        Collection是单列集合的祖宗接口,它的功能是全部单列集合都可以继承使用

Collection集合常用API:

Collection集合的遍历方式

方式一:迭代器

        遍历就是一个一个的把容器中的元素访问一遍
        迭代器在Java中的代表是Iterator,迭代器是集合的专用遍历方式

Collection集合获取迭代器

Iterator中的常用方法

迭代器执行流程

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

1.迭代器的默认位置在哪里?
        Iterator<E> iterator():得到迭代器对象,默认指向当前集合的索引0

2.迭代器如果取元素越界会出现什么问题?
        会出现NoSuchElementException异常


方式二:增强for循环

        既可以遍历集合也可以遍历数组

格式:

for(元素数据类型 变量名 : 数组或者Collection集合) {

         //在此处使用变量即可,该变量就是元素

}

例:

Collection<String> list = new ArrayList<>();

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

注:
        修改第三方变量的值不会影响集合中的元素

1.增强for可以遍历哪些容器?
        既可以遍历集合也可以遍历数组


方式三:lambda表达式

        JDK 8开始的新技术Lambda表达式,提供了一种更简单更直接的遍历集合的方式

Collection结合Lambda遍历的API

Collection<String> lists = new ArrayList<>();

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

//lists.forEach(s -> System.out.println(s));

Collection集合存储自定义类型的对象

需求:
        某影院系统需要在后台存储上述三部电影,然后依次展示出来
分析:
        定义一个电影类,定义一个集合存储电影对象
        创建3个电影对象,封装相关数据,把3个对象存入到集合中去
        遍历集合中的3个对象,输出相关信息

public class Movie {
    private String name;
    private double score;
    private String actor; // 主演

    public Movie() {
    }

    public Movie(String name, double score, String actor) {
        this.name = name;
        this.score = score;
        this.actor = actor;
    }

    public String getName() {
        return name;
    }

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

    public double getScore() {
        return score;
    }

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

    public String getActor() {
        return actor;
    }

    public void setActor(String actor) {
        this.actor = actor;
    }

    @Override
    public String toString() {
        return "Movie{" +
                "name='" + name + '\'' +
                ", score=" + score +
                ", actor='" + actor + '\'' +
                '}';
    }
}
import java.util.ArrayList;
import java.util.Collection;

public class TestDemo {
    public static void main(String[] args) {
        // 1、定义一个电影类
        // 2、定义一个集合对象存储3部电影对象
        Collection<Movie> movies = new ArrayList<>();
        movies.add(new Movie("《你好,李焕英》", 9.5, "张小斐,贾玲,沈腾,陈赫"));
        movies.add(new Movie("《唐人街探案》", 8.5, "王宝强,刘昊然,美女"));
        movies.add(new Movie("《刺杀小说家》",8.6, "雷佳音,杨幂"));

        System.out.println(movies);

        // 3、遍历一下这三个电影对象
        for (Movie movie : movies) {
            System.out.println(movie.getName());
            System.out.println(movie.getActor());
            System.out.println(movie.getScore());
            System.out.println("-------------------");
        }

    }
}

1.集合中存储的是元素的什么信息?
        集合中存储的是元素对象的地址 

List系列集合

List系列集合特点和特有API

List系列集合特点:
        ArrayList LinekdList :有序,可重复,有索引。
        有序:存储和取出的元素顺序一致
        有索引:可以通过索引操作元素
        可重复:存储的元素可以重复

List集合特有方法

        List集合因为支持索引,所以多了很多索引操作的独特API,其他Collection的功能List也都继承了

1.List系列集合特点
        ArrayList LinekdList :有序,可重复,有索引


2.List的实现类的底层原理
        ArrayList 底层是基于数组实现的,根据索引查询元素快,增删相对慢
        LinkedList 底层基于双链表实现的,查询元素慢,增删首尾元素是非常快的


List集合的遍历方式小结

方式一:迭代器 
方式二:增强for循环
方式三:Lambda表达式
方式四:or循环(因为List集合存在索引)

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

/**
    拓展:List系列集合的遍历方式有:4种。

    List系列集合多了索引,所以多了一种按照索引遍历集合的for循环。

    List遍历方式:
        (1)for循环。(独有的,因为List有索引)。
        (2)迭代器。
        (3)foreach。
        (4)JDK 1.8新技术。
 */
public class ListDemo {
    public static void main(String[] args) {
        ArrayList<String> lists = new ArrayList<>();
        lists.add("java1");
        lists.add("java2");
        lists.add("java3");

        /** (1)for循环。 */
        System.out.println("-----------------------");
        for (int i = 0; i < lists.size(); i++) {
            String ele = lists.get(i);
            System.out.println(ele);
        }

        /** (2)迭代器。 */
        System.out.println("-----------------------");
        Iterator<String> it = lists.iterator();
        while (it.hasNext()){
            String ele = it.next();
            System.out.println(ele);
        }

        /** (3)foreach */
        System.out.println("-----------------------");
        for (String ele : lists) {
            System.out.println(ele);
        }

        /** (4)JDK 1.8开始之后的Lambda表达式  */
        System.out.println("-----------------------");
        lists.forEach(s -> {
            System.out.println(s);
        });
    }
}

ArrayList集合

        ArrayList集合支持索引

ArrayList集合的对象的创建

 

ArrayList集合的添加元素的方法

泛型:

        ArrayList<E>:其实就是一个泛型类,可以在编译阶段约束集合对象只能操作某种数据类型

例:

        ArrayList<String> :此集合只能操作字符串类型的元素。
        ArrayList
<Integer>:此集合只能操作整数类型的元素

注:泛型只能支持引用数据类型,不支持基本数据类型

ArrayList集合常用方法

ArrayList集合底层原理
        ArrayList底层是基于数组实现的:根据索引定位元素快,增删需要做元素的移位操作
        第一次创建集合并添加第一个元素的时候,在底层创建一个默认长度为10的数组

List<String> list = new ArrayList<>();
list.add("a");

List集合存储的元素要超过容量:继续生成长度为10的数组


LinkedList集合

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

LinkedList集合的特有功能

LinkedList集合底层原理

集合的并发修改异常问题

哪些遍历存在问题?

        迭代器遍历集合且直接用集合删除元素的时候可能出现。
        增强for循环遍历集合且直接用集合删除元素的时候可能出现


哪种遍历且删除元素不出问题?

        迭代器遍历集合但是用迭代器自己的删除方法操作可以解决。
        使用for循环遍历并删除元素不会存在这个问题

集合工具类Collections

Collections集合工具类

        java.utils.Collections


作用:

        Collections并不属于集合,是用来操作集合的工具类

Collections常用的API

Collections排序相关API

        只能对于List集合的排序

排序方式1:

排序方式2:

Set系列集合

Set系列集合特点和特有API

Set系列集合特点:

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

Set集合实现类特点

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


        TreeSet:排序、不重复、无索引

Set集合的功能上基本上与CollectionAPI一致


实现类HashSet集合

        底层采取哈希表存储的数据

性能:哈希表是一种对于增删改查数据性能都较好的结构

哈希表的组成
        JDK8之前的,底层使用数组+链表组成
        JDK8开始后,底层采用数组+链表+红黑树组成

哈希值

        是JDK根据对象的地址按照某种规则算出来的int类型的数值

Object类的API

        public int hashCode​():返回对象的哈希值

对象的哈希值特点

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

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

HashSet1.7

HashSet1.8

HashSet去重复


实现类LinkedHashSet集合

        有序 不重复 无索引

有序:

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

原理:

        底层数据结构是依然哈希表,只是每个元素之间用的是一个双链表的机制记录存储的顺序


实现类TreeSet集合

        可排序 不重复 无索引

可排序:

        按照元素的大小默认升序(有小到大)排序

性能:

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

注意:

        TreeSet集合是一定要排序的,可以将元素按照指定的规则进行排序

TreeSet集合默认的规则:

        对于数值类型:Integer , Double,官方默认按照大小进行升序排序
        对于字符串类型:默认按照首字符的编号升序排序
        对于自定义类型:如Student对象,TreeSet无法直接排序

自定义排序规则:

        方式一:

                让自定义的类(如学生类)实现Comparable接口重写里面的compareTo方法来定制比较规则
        方式二:

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

两种方式中,关于返回值的规则:
        如果认为第一个元素大于第二个元素返回正整数即可 值1>值2: 1 
        如果认为第一个元素小于第二个元素返回负整数即可 值1<值2:-1 
        如果认为第一个元素等于第二个元素返回0即可,此时Treeset集合只会保留一个元素,认为两者重复 值1=值2:0


注意:

        如果TreeSet集合存储的对象有实现比较规则集合也自带比较器,默认使用集合自带的比较器排序

Collection体系的特点、使用场景总结

1.  如果希望元素可以重复,又有索引,索引查询要快?
        用ArrayList集合,基于数组的(用的最多)


2.  如果希望元素可以重复,又有索引,增删首尾操作快?
        用LinkedList集合,基于链表


3.  如果希望增删改查都快,但是元素不重复、无序、无索引?
        用HashSet集合,基于哈希表


4.  如果希望增删改查都快,但是元素不重复、有序、无索引?
        用LinkedHashSet集合,基于哈希表双链表


5.  如果要对对象进行排序?
        用TreeSet集合,基于红黑树,后续也可以用List集合实现排序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值