【JAVA】集合(Collection、Map)

news2024/11/27 4:22:09

集合和数组都是容器

数组:类型确定,长度固定,可以存储基本类型和引用类型的数据

集合:类型可以不固定,大小可变,只能存储引用数据类型的数据

Collection单列单列集合,每个元素只包含一个值
Map双列双列结合,每个元素包含两个值(键值对)

1 Collection

List(接口)系列集合:添加元素是有序、可重复、有索引

  • ArrayList、LinkedList(实现类):有序、可重复、有索引

Set(接口)系列结合:添加元素是无序、不重复、无索引的

  • HashSet(实现类):无序、不重复、无索引。LinkedHashSet:有序、不重复、无索引
// 不定义集合的数据类型
Collection list = new ArrayList();
// 定义集合的数据类型,只能支持引用数据类型
Collection<Integer> list = new ArrayList<>();
// 添加元素
list.add('a');
Collection hash = new HashSet();
// 添加元素
hash.add('a');

1.1 Collection

1.1.1 常用API 

public boolean add(E e)

把给定的对象添加到当前集合中

public void clear()

清空集合中所有的元素

public boolean remove(E e)

把给定的对象在当前集合中删除

public boolean contains(Object obj)

判断当前集合中是否包含给定的对象

public boolean isEmpty()

判断当前集合是否为空

public int size()

返回集合中元素的个数。

public Object[] toArray()

把集合中的元素,存储到数组中

1.1.2 使用

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

  • 用ArrayList集合,基于数组的。(用的最多)

如果希望元素可以重复,又有索引,增删首尾操作快?

  • 用LinkedList集合,基于链表的。

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

  • 用HashSet集合,基于哈希表的.

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

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

如果要对对象进行排序。

  • 用TreeSet集合,基于红黑树。后续也可以用List集合实现排序。

扩展知识

可变参数:可以接收多个数据(本质是一个数组)(一个形参列表可变参数只有一个,可变参数必须放在形参列表的最后)

// 数据类型...参数名称
public static void sum(int...nums){
}

1.1.3 Collections集合工具类

public static <T> boolean addAll(Collection<? super T> c, T... elements)

给集合对象批量添加元素

public static void shuffle(List<?> list)

打乱List集合元素的顺序

List<Integer> test = new Arraylist<>();
// 批量添加数据
Collection.addAll(test,1,2,3,4,5);
//打乱list集合顺序
Collection.shuffle(test);

排序(只针对list)

public static <T> void sort(List<T> list)

将集合中元素按照默认规则排序

public static <T> void sort(List<T> list,Comparator<? super T> c)

将集合中元素按照指定规则排序

Collections.sort(test);

方式一

  • 让自定义的类(如学生类)实现Comparable接口重写里面的compareTo方法来定制比较规则。
// Student类里重写CompareTo方法
// 按年龄升序
@Override
public int compareTo(String o){
    return this.age - o.age;
}

方式二

  • 设置Comparator接口对应的比较器对象,来定制比较规则。
     
// 按年龄降序排
Collections.sort(stulist, new Comparator<Student>(){
    @Override
    public int compare(Student o1,Student o2){
        return o2.getAge() - o1.getAge();
    }
});

1.2 List集合

有序、可重复、有索引

1.2.1 ArrayList

基于数组实现的,查询块,增删慢。

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

void add(int index,E element)

在此集合中的指定位置插入指定的元素

E remove(int index)

删除指定索引处的元素,返回被删除的元素

E set(int index,E element)

修改指定索引处的元素,返回被修改的元素

E get(int index)

返回指定索引处的元素

删除重复相邻元素

foreach遍历删除、lambda表达式(会出现bug)

// 迭代器遍历删除
Iterator<String> it = list.iterator();
        while (it.hasNext()){
            String ele = it.next();
            if("Java".equals(ele)){
                list.remove("要删除元素");
                it.remove(); // 使用迭代器删除当期位置的元素,保证不后移,能够成功遍历到全部元素!
            }
        }
// for循环删除
for (int i = list.size() - 1; i >= 0; i--) {
    String ele = list.get(i);
    if("Java".equals(ele)){
        list.remove("要删除元素");
    }
}
// for循环删除2
for (int i = 0; i < list.size(); i++) {
    String ele = list.get(i);
    if("要删除元素".equals(ele)){
        list.remove("要删除元素");
        i--;
    }
}

1.2.2 LinkedList

基于双链表实现,查询慢,增删首尾元素快

LinkedList<string> a = new LinkedList<>();
a.addFirst("hhhh");

public void addFirst​(E e)

在该列表开头插入指定的元素

public void addLast​(E e)

将指定的元素追加到此列表的末尾

public E getFirst​()

返回此列表中的第一个元素

public E getLast​()

返回此列表中的最后一个元素

public E removeFirst​()

从此列表中删除并返回第一个元素

public E removeLast​()

从此列表中删除并返回最后一个元素

1.3 Set集合

无序、不重复、无索引

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

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

Set<String> sets = new HashSet<>();
sets.add("aaa");

1.3.1 HashSet

采取哈希表存储

哈希表增删改查都很快(JDK8前,底层使用数组+链表组成;JDK8后,底层采用数组+链表+红黑树组成)

  • 哈希值是JDK根据对象的地址,按照某种规则算出来的int类型的数值
  • 同一对象多次调用hashCode​()方法,返回的哈希值相同;
  • 默认情况下,不同对象的哈希值是不同的
public int hashCode ​()
返回对象的哈希值
Set<String> sets = new HashSet<>();

1.3.1.1 LinkedHashSet

HashSet的子类,有序(存储和取出的顺序一致)、不重复、无索引

底层基于哈希表,使用双链表记录添加

1.3.2 TreeSet

不重复、无索引、可排序(按元素的大小默认升序排)

底层基于红黑树的数据结构实现排序,增删改查都很快

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

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

对于没有默认规则的,需自定义规则(若这两个都定义了,则采用就近的规则)

方式一

  • 让自定义的类(如学生类)实现Comparable接口重写里面的compareTo方法来定制比较规则。
// Student类里重写CompareTo方法
// 按年龄升序
@Override
public int compareTo(String o){
    return this.age - o.age;
}

方式二

  • TreeSet集合有参数构造器,可以设置Comparator接口对应的比较器对象,来定制比较规则。
     
// 按年龄降序排
Set<Student> s1 = new TreeSet<>(new Comparator<Student>(){
    @Override
    public int compare(Student o1,Student o2){
        return o2.getAge() - o1.getAge();
    }
});

2 Map

Map集合每个元素是键值对,有点像字典类型

HashMap元素按照键是无序,不重复,无索引,值不做要求。Map体系一致
LinkedHashMap元素按照键是有序,不重复,无索引,值不做要求。
TreeMap元素按照建是排序,不重复,无索引的,值不做要求。
Map<String, Integer> maps = new HashMap<>();

2.1 常用API

V put(K key,V value)

添加元素

V remove(Object key)

根据键删除键值对元素

void clear()

移除所有的键值对元素

boolean containsKey(Object key)

判断集合是否包含指定的键

boolean containsValue(Object value)

判断集合是否包含指定的值

boolean isEmpty()

判断集合是否为空

int size()

集合的长度,也就是集合中键值对的个数

2.2 遍历方法

方式一:键找值的方式遍历:先获取Map集合全部的键,再根据遍历键找值。

Set<K> keySet()获取所有键的集合
V get(Object key)根据值获取键

方式二:键值对的方式遍历,把“键值对“看成一个整体,难度较大。

Set<Map.Entry<K,V>> entrySet()

获取所有键值对对象的集合

getKey()

获得键

getValue()

获取值

 // 把Map集合转换成Set集合
Set<Map.Entry<String, Integer>> entries = maps.entrySet();  
Set entries = new HashSet();                                                                    
for (Map.Entry<String, Integer> entry : entries) {
    String key = entry.getKey(); // 取键
    Integer value = entry.getValue(); // 取值
    System.out.println(key + "==>" + value);
}

方式三:JDK 1.8开始之后的新技术:Lambda表达式。

default void forEach(BiConsumer<? super K, ? super V> action)

结合lambda遍历Map集合

// 简化前
maps.forEach(new BiConsumer<String, Integer>() {
    @Override
    public void accept(String key, Integer value) {
        System.out.println(key + "===>" + value);
    }
});
// 简化后
maps.forEach((k,v) -> {
    System.out.println(k + "--->" + v);
});

2.3 HashMap*

HashMap是Map里面的一个实现类。

  • 特点都是由键决定的:无序、不重复、无索引
  • 底层是哈希表结构的。增删改查的性能都较好。
  • 依赖hashCode方法和equals方法保证的唯一。
  • 如果要存储的是自定义对象,需要重写hashCodeequals方法。

2.4 LinkedHashMap

  • 由键决定:有序(保证存储和取出的元素顺序一致)、不重复、无索引。
  • 原理:底层数据结构是依然哈希表,只是每个键值对元素又额外的多了一个双链表的机制记录存储的顺序

2.5 TreeMap

  • 由键决定特性:不重复、无索引、可排序(按照键数据的大小默认升序(有小到大)排序。只能对键排序。)
  • TreeMap集合是一定要排序的,可以默认排序,也可以将键按照指定的规则进行排序
  • TreeMap跟TreeSet一样底层原理是一样的。

TreeMap集合自定义排序规则有2

  • 类实现Comparable接口,重写比较规则。
  • 集合自定义Comparator比较器对象,重写比较规则。

3 遍历方式

迭代器

// 得到集合lists对象的迭代器对象
Iterator<String> it = lists.iterator();
while(it.hasNext()){
    // it.next() 获取元素
    String ele = it.next();
    System.out.println(ele);
}

foreach

Collection<String> list = new ArrayList<>();
...
for(String ele : list) {
    System.out.println(ele);
}

Lambda表达式

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

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

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

4 存储自定义对象

public class SystemDemo {
    public static void main(String[] args) {
        // 定义一个电影类的集合对象
        Collection <Movie> movies = new ArrayList<>();
        movies.add(new Movie("《肖生克的救赎》", 9.7,  "罗宾斯"));
        movies.add(new Movie("《霸王别姬》", 9.6 ,  "张国荣、张丰毅"));
        movies.add(new Movie("《阿甘正传》", 9.5,  "汤姆.汉克斯"));
        // 打出数组内容
        System.out.println(movies);
        // 遍历内容
        for (Movie movie : movies) {
            System.out.println("片名:" + movie.getName());
            System.out.println("评分:" + movie.getScore());
            System.out.println("主演:" + movie.getAcotr());
        }
    }
}
public class Movie {
    private String name;
    private double score;
    private String acotr;
    public Movie(String name, double score, String acotr) {
        this.name = name;
        this.score = score;
        this.acotr = acotr;
    }
}

集合中存储的是元素对象的地址

5 常见数据结构

栈:先进后出,后进先出

队列:先进先出,后进后出

数组:查询快,增删慢

  • 查询速度快:查询数据通过地址值和索引定位,查询任意数据耗时相同。(元素在内存中是连续存储的)
  • 删除效率低:要将原始数据删除,同时后面每个数据前移。
  • 添加效率极低:添加位置后的每个数据后移,再添加元素。

链表:查询慢(数据从头开始查找),增删相对快

二叉树:只有一个根节点,每个节点最多支持两个直接子节点

查找二叉树

  • 每一个节点上最多有两个子节点
  • 左子树上所有节点的值都小于根节点的值
  • 右子树上所有节点的值都大于根节点的值
     

平衡二叉树:任意节点的左右两个子树的高度差不超过1,任意节点的左右两个子树都是一颗平衡二叉树

红黑数:一种自平衡的二叉查找树,是计算机科学中用到的一种数据结构。

红黑树增删改查性能都很好

  • 每—个节点或是红色的。或者是黑色的,根节点必须是黑色。、
  • 如果一个节点没有子节点或者父节点,则该节点相应的指针属性值为Nil,这些Nil视为叶节点,叶节点是黑色的。
  • 如果某一个节点是红色,那么它的子节点必须是黑色(不能出现两个红色节点相连的情况)。
  • 对每一个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点。
     

6 泛型

  • 泛型:是JDK5中引入的特性,可以在编译阶段约束操作的数据类型,并进行检查。
  • 泛型的格式:<数据类型>;注意:泛型只能支持引用数据类型。
  • 集合体系的全部接口和实现类都是支持泛型的使用的。

泛型的好处:

  • 统一数据类型。
  • 把运行时期的问题提前到了编译期间,避免了强制类型转换可能出现的异常,因为编译阶段类型就能确定下来。

泛型类

// 修饰符 class 类名<泛型变量>{  }
public class MyArrayList<T> {  
}

// 调用
MyArrayList<String> myl = new MyArrayList<>();

此处泛型变量T可以随便写为任意标识。常见的如E、T.K、V等。

作用:编译阶段可以指定数据类型,类似于集合的作用。

泛型方法

定义方法时同时定义了泛型的方法就是泛型方法。

// 修饰符 <泛型变量> 方法返回值 方法名称(形参列表){}
public <T> void show(T t) {  }

作用:方法中可以使用泛型接收一切实际类型的参数,方法更具备通用性。

方法中可以使用泛型接收一切实际类型的参数,方法更具备通用性

泛型接口

使用了泛型定义的接口就是泛型接口

// 修饰符 interface 接口名称<泛型变量>{}
public interface Data<E>{}

作用:泛型接口可以让实现类选择当前功能需要操作的数据类型,实现类可以在实现接口的时候传入自己操作的数据类型,这样重写的方法都将是针对于该类型的操作。

通配符

? 可以在“使用泛型”的时候代表一切类型。

E T K V 是在定义泛型的时候使用的。

        ArrayList<BMW> bmws = new ArrayList<>();
        bmws.add(new BMW());
        go(bmws);

        ArrayList<BENZ> benzs = new ArrayList<>();
        benzs.add(new BENZ());
        go(benzs);

//        ArrayList<Dog> dogs = new ArrayList<>();
//        dogs.add(new Dog());
//        go(dogs);
    }
    /**
        定义方法,让汽车可以一起参加比赛
     */
// ? extends Car: ?必须是Car或者其子类   泛型上限

// ? super Car : ?必须是Car或者其父类   泛型下限
    public static void go(ArrayList<? extends Car> cars){

    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/877547.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

伴随矩阵的特征值跟原矩阵特征值居然有关系!!!附证明

文章目录 论点&#xff1a;A与其伴随矩阵的特征值相乘等于|A|证明证明证明中涉及的相关定理&#xff1a;1.逆矩阵与伴随矩阵的关系2.A可逆时&#xff0c;A的逆矩阵的特征值是原矩阵特征值的倒数 论点&#xff1a;A与其伴随矩阵的特征值相乘等于|A| 证明 证明 证明中涉及的相关…

html css实现爱心

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><style>/* 爱心 */.lo…

基于Matlab实现小偷体貌识别仿真(附上源码+数据集)

小偷体貌识别是一种应用于安全领域的重要技术&#xff0c;它利用计算机视觉和机器学习的方法&#xff0c;通过对监控视频中的人体特征进行提取和分析&#xff0c;来识别出可能的小偷。在本文中&#xff0c;我们将介绍如何使用Matlab实现小偷体貌识别的仿真。 文章目录 介绍部分…

测牛学堂:软件测试工程师都要懂的软件开发模型总结

软件开发模型之快速原型 之前跟大家介绍了最早期的瀑布模型。今天聊一下快速原型模型。 快速原型&#xff0c;在初步确定用户需求之后&#xff0c;快速构造出一个原型项目&#xff0c;可以跟用户展示软件的功能&#xff0c;用户根据原型进行评审&#xff0c;提出更进一步的细…

JavaWeb-Servlet服务连接器(终)

上一篇文章JavaWeb-Servlet服务连接器&#xff08;三&#xff09;_Alphamilk的博客-CSDN博客 目录 1.ServletContext通信 会话技术Cookie与Session 1.Cookie 2.Session 1.ServletContext通信 概念&#xff1a;代表了整个web应用&#xff0c;用于与服务器实现通信 可以通…

6.2 口令破解攻击

数据参考&#xff1a;CISP官方 目录 口令安全问题口令破解攻击口令破解安全防护口令使用安全管理 一、口令安全问题 什么是口令 身份验证的机制&#xff0c;俗称 “密码"&#xff0c;对应英文单词为 password成本较低&#xff0c;得到广泛应用信息安全中的 “密码”…

基于 Nginx All In One 的 Outline Wiki 部署方法

1. Outline 简介 官网&#xff1a;https://www.getoutline.com/ Outline 是一个开源的知识库和团队协作工具&#x1f9e0;&#xff0c;旨在帮助团队共享、组织和协作文档&#x1f4dd;。它提供了一个简洁的界面&#xff0c;使用户能够轻松创建、编辑和查看文档。 以下是 Out…

sudo免密码设置以及设置失败解决方法

使用sudo visudo修改\etc\sudoers文件 打开后有很多已有的设置大致格式username ALL(ALL:ALL) ALL&#xff0c;都不要动&#xff01; 在文件结尾加上一句话&#xff1a; username ALL(ALL:ALL) NOPASSWD: ALLusername就是目前你这个账户的名字&#xff0c;开机时会输密码登录…

Nginx访问日志及巡检统计

一、前言 二、词汇解释 2.1、pv和uv的区别 PV&#xff08;Page View访问量/也卖弄浏览数&#xff09;&#xff1a;指在一定统计周期内&#xff0c;用户每次刷新网页一次即计算一次。PV高不一定代表来访者多:PV与来访者的数量成正比&#xff0c;但是PV并不直接决定页面的真实来…

同样的字符串,有一些事长度为3,有一些长度为2,导致Convert.ToByte(macStringArray[i], 16);出错

同样的字符串&#xff0c;有一些事长度为3&#xff0c;有一些长度为2,导致Convert.ToByte(macStringArray[i], 16);出错。 最后&#xff0c;把长度为2的复制过去&#xff0c;就好了。 要复制“1C- 只复制1C不行 { “pc101”:“1C-69-7A-BD-05-C4”, “pc102”:“1C-69-7A-BD…

Selenium自动化测试实战之自动化测试基础

自动化测试概念 是把以人为驱动的测试转化为机器执行的一种过程&#xff0c;它是一种以程序测试程序的过程。 自动化只是测试方式&#xff0c;跟测试阶段无关。 可以把任何测试工作写一个程序自动化实现都可以称为自动化测试。 selenium自动化测试&#xff1a;2023最新的Sele…

docker可视化工具Portainer

1:Portainer简介 Portainer是一个docker可视化管理工具&#xff0c;可以非常方便地管理docker镜像容器。官网地址&#xff1a;https://www.portainer.io/ 注&#xff1a;现在Portainer有BE&#xff08;收费&#xff09;和CE&#xff08;免费&#xff09;版本&#xff0c;安装的…

答疑:Arduino IDE配置其他开发板下载速度慢

基于案例&#xff1a;Linux环境Arduino IDE中配置ATOM S3 通常&#xff0c;网络问题较多&#xff0c;可以使用一些技巧。 https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/arduino/package_m5stack_index.json 没有配置&#xff0c;不支持M5Stack&#xff08;ESP32&…

SpringCloud教程(上)

目录 一、微服务架构理论入门 1.1、什么是微服务&#xff1f; 1.2、微服务简单总结 1.3、微服务的优缺点 1.4、微服务、分布式、集群的区别 1.5、SpringCloud停更替换技术说明 二、微服务架构编码构建 2.1、微服务cloud整体聚合父工程Project 2.1.1、New Project 2.1…

【【萌新的STM32学习-9】】

萌新的STM32学习-9 我们在使用某个外设&#xff0c;必须线使能该外设时钟 SYSTEM 文件夹里面的代码由正点原子提供&#xff0c;是 STM32F1xx 系列的底层核心驱动函数&#xff0c; 可以用在 STM32F1xx 系列的各个型号上面&#xff0c;方便大家快速构建自己的工程。本章&#xf…

这所985非常难考,却无数人趋之若鹜!

一、学校及专业介绍 厦门大学&#xff08;Xiamen University&#xff09;&#xff0c;简称厦大&#xff08;XMU&#xff09;&#xff0c;位于福建省厦门市&#xff0c;位列国家“双一流”、“985工程”、“211工程”重点建设高校。 1.1 招生情况 厦门大学初试考847信号与系统…

Android AOSP源码编译——AOSP整编(二)

切换到源码目录下执行下面命令 1、初始化环境 . build/envsetup.sh //清除缓存 make clobber2、选择编译目标 lunchAOSP 预制了很多 Product。这里为了简单我们先不用真机&#xff0c;而是选择模拟器的方式&#xff0c;对于 x86_64 模拟器&#xff0c;我们选择的是 aosp_x86…

DevOps系列文章 之 Gitlab+Docker自动部署SpringBoot

1.环境要求 以下服务器的操作系统均为Centos7 服务器A&#xff1a;Gitlab服务器B&#xff1a;GitlabRunner、Docker、docker-compose、Java1.8、maven3.6.3、git ps&#xff1a;这里可以把服务器B的GitlabRunner、Java1.8、maven3.6.3、git单独提出来&#xff0c;独立部署&a…

Photoshop多图片与多窗口下排列操作方法

首先&#xff0c;在Photoshop中打开6张图片&#xff0c;在“窗口”菜单下切换窗口排列状态&#xff1a; 在 “窗口”菜单下对窗口进行排列&#xff0c;分别呈现如下&#xff1a; &#xff08;一&#xff09;. 点击“窗口” -> “排列”->"全部垂直拼贴": &am…

编程大师之路:Java必读书籍引领程序员进阶

编程大师之路&#xff1a;Java必读书籍引领程序员进阶 一、Java基础 1.1 Java基础入门 ​ 由传智播客高教产品研发部编著的《Java基础入门》从初学者的角度详细讲解了Java开发中重点用到的多种技术。全书共11章&#xff0c;包括Java开发环境的搭建及其运行机制、基本语法、面向…