Java 进阶集合Set、Map(二)

简介: Java 进阶集合Set、Map

一、Set集合

1、HashSet集合

1)原理

底层采用哈希表存储数据

2)组成

jdk8之前:底层数组+链表组成

jdk8之后:底层数组+链表+红黑树组成

3)哈希值

对象的内存地址经过处理后的结构,由于每个对象的内存地址都不一样,所以哈希码也不一样。更重要的是:这里的内存地址是JVM虚拟机虚拟出来的地址,并不是真实的物理内存地址

4)哈希值特点

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

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

5)jdk8哈希表流程:

Constructs a new, empty set; the backing HashMap instance has default initial capacity (16) and load factor (0.75).

创建一个新的空集合,默认初始值是16,加载因子(0.75)

根据元素的哈希值和数组的长度计算出应存入的位置

首先判断当前位置是否为NULL,空则直接存入,非空则equals方法比较属性值,相同则不存,不同则存入数组

当数组存储满足16*0.75=12时自动扩容,每次扩容会是当前容量的2倍

d08ba0f00ece82d72bfbbbe476d38ed.png

import java.util.HashSet;
public class ClassStructure {
    public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        set.add("aa");
        set.add("bb");
        set.add("cc");
        set.add("aa");
        set.add("ee");
        set.add("ff1");
        set.add("ff2");
        set.add("ff3");
        System.out.println(set);
        //哈希值
        System.out.println(set.hashCode());
    }
}

2、LinkedHashSet集合

1)概述

有序、不重复、无索引

有序指保证存储和取出元素顺序一致

2)原理

底层数据结构哈希表,每个元素增加双链表机制记录数据存储顺序

5b8aed8a9ea8b87fb843eb8aea7be1e.png

f16520370cfd8f03e6252ee5df3f9cc.png

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
public class ClassStructure {
    public static void main(String[] args) {
        Set set = new LinkedHashSet<>();
        set.add("aa");
        set.add(123);
        set.add(456);
        set.add("hello");
        System.out.println(set);
    }
}

3、TreeSet集合

不重复、无索引、可排序

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

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

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

1)默认规则

对于数值类型:Integer , Double,默认升序排序。

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

对于自定义类型对象,TreeSet无法直接排序。

2) 自定义规则

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

eef540d8eb5a1d4b121cc4576c0529e.png

public class Student {
    private int id;
    private String name;
    private int age;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    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 String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
public class ClassStructure {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.setId(1);
        stu.setName("zhangsan");
        stu.setAge(11);
        Student stu1 = new Student();
        stu1.setId(3);
        stu1.setName("zhangsan3");
        stu1.setAge(33);
        Student stu2 = new Student();
        stu2.setId(2);
        stu2.setName("zhangsan2");
        stu2.setAge(22);
        Student stu3 = new Student();
        stu3.setId(5);
        stu3.setName("zhangsan5");
        stu3.setAge(55);
        Set<Student> set = new TreeSet<>(
                new Comparator<Student>() {
                    @Override
                    public int compare(Student o1, Student o2) {
                        return o1.getId()-o2.getId();
                    }
                }
        );
        set.add(stu);
        set.add(stu1);
        set.add(stu2);
        set.add(stu3);
        for (Student id:set){
            System.out.println(id);
        }
    }
}

让自定义的类,实现Comparable接口重写里面的compareTo方法来定制比较规则。

99f6137de347a0b2db25d21fea37094.png

public class Student implements Comparable<Student>{
    private int id;
    private String name;
    private int age;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    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 String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    /*
    默认升序
     */
    @Override
    public int compareTo(Student o) {
        return this.id - o.id;
    }
}
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
public class ClassStructure {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.setId(1);
        stu.setName("zhangsan");
        stu.setAge(11);
        Student stu1 = new Student();
        stu1.setId(3);
        stu1.setName("zhangsan3");
        stu1.setAge(33);
        Student stu2 = new Student();
        stu2.setId(2);
        stu2.setName("zhangsan2");
        stu2.setAge(22);
        Student stu3 = new Student();
        stu3.setId(5);
        stu3.setName("zhangsan5");
        stu3.setAge(55);
        Set<Student> set = new TreeSet<>();
        set.add(stu);
        set.add(stu1);
        set.add(stu2);
        set.add(stu3);
        for (Student id:set){
            System.out.println(id);
        }
    }
}

4、可变参数(动参)

定义

可变参数用在形参中可以接收多个数据。

可变参数的格式:数据类型…参数名称

作用

接收参数非常灵活,方便。可以不接收参数,可以接收1个或者多个参数,也可以接收一个数组

可变参数在方法内部本质上就是一个数组。

注意

一个形参列表中可变参数只能有一个

可变参数必须放在形参列表的最后面

题目(实战),需求:

假如需要定义一个方法求和,该方法可以灵活的完成如下需求:

计算1个数据的和。

计算2个数据的和。

计算3个数据的和。

计算n个数据的和,甚至可以支持不接收参数进行调用。

7279934d79e860112a487a469344ae8.png

public class ClassSructure {
    public static void Test(Integer... args) {
        int sum = 0;
        for (int ag : args) {
            sum += ag;
        }
        System.out.println(sum);
    }
    public static void main(String[] args) {
        Test(1);
        Test(1, 2);
        Test(1, 2, 3);
    }
}

二、Map集合

1、概述

Map是双列集合,每个元素包含两个数据,格式(Key=Value),也称为键值对集合

2、特点

Map集合的键是无序,不重复的,无索引的,值不做要求(可以重复)

Map集合后面重复的键对应的值会覆盖前面重复键的值,键值对都可以为null。

3、常用API

方法名 解释

V put(K key,V value) 添加元素

V remove(Object key) 根据键删除键值对元素

void clear() 清空所有的键值对元素

int size() 集合的长度,集合中键值对的个数

boolean containsKey(Object key) 判断集合是否包含指定的键

boolean containsValue(Object value) 判断集合是否包含指定的值

boolean isEmpty() 判断集合是否为空

4、HashMap 用的最多

元素按照键是无序,不重复,无索引,值不做要求(可以重复)

-实战根据key求value

038603882c73357e7416247870f2711.png

import java.util.HashMap;
import java.util.Map;
public class ClassStructure {
    public static void main(String[] args) {
        Map<Integer,String> map = new HashMap<>();
        map.put(1,"数学");
        map.put(2,"语文");
        map.put(3,"英语");
        map.put(4,"物理");
        map.put(5,"政治");
        String str = map.get(1);
        System.out.println(str);
        String str1 = map.get(3);
        System.out.println(str1);
    }
}

5、LinkedHashMap

元素按照键是有序,不重复,无索引,值不做要求

实战 判断key是否存在

f0669cc8cc59d8a55ee4142620c0af5.png

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
public class ClassStructure {
    public static void main(String[] args) {
        Map<Integer,String> map = new LinkedHashMap<>();
        map.put(1,"数学");
        map.put(2,"语文");
        map.put(3,"英语");
        map.put(4,"物理");
        map.put(5,"政治");
        boolean str = map.containsKey(1);
        System.out.println(str);
        boolean str1 = map.containsKey(6);
        System.out.println(str1);
    }
}

6、TreeMap

元素按照建是排序,不重复,无索引的,值不做要求

实战 参考TreeSet

Set系列集合的底层就是Map实现的,只是Set集合中的元素只要键数据


相关文章
|
21天前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
24天前
|
Java C# Swift
Java Stream中peek和map不为人知的秘密
本文通过一个Java Stream中的示例,探讨了`peek`方法在流式处理中的应用及其潜在问题。首先介绍了`peek`的基本定义与使用,并通过代码展示了其如何在流中对每个元素进行操作而不返回结果。接着讨论了`peek`作为中间操作的懒执行特性,强调了如果没有终端操作则不会执行的问题。文章指出,在某些情况下使用`peek`可能比`map`更简洁,但也需注意其懒执行带来的影响。
Java Stream中peek和map不为人知的秘密
|
9天前
|
Go 定位技术 索引
Go 语言Map(集合) | 19
Go 语言Map(集合) | 19
|
8天前
|
存储 前端开发 API
ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用
该文章详细介绍了ES6中Set和Map数据结构的特性和使用方法,并探讨了它们在前端开发中的具体应用,包括如何利用这些数据结构来解决常见的编程问题。
ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用
|
10天前
|
存储 安全 Java
Java 常用集合分类
Java 常用集合分类
13 2
|
2月前
|
存储 算法 Java
Java中的集合框架深度解析与实践
【8月更文挑战第31天】在Java编程的海洋中,集合框架扮演着不可或缺的角色。本文将带你领略Java集合框架的魅力,从理论到实践,深入浅出地探索List、Set和Map等核心接口的使用技巧。我们将通过具体代码示例,展示如何在日常开发中高效运用这些工具,让你的代码更加优雅和高效。无论你是初学者还是有经验的开发者,这篇文章都将为你打开一扇通往Java集合世界的大门。
|
2月前
|
存储 人工智能 Java
JAVA集合
【8月更文挑战第31天】
|
2月前
|
安全 Java
【Java集合类面试三】、Map接口有哪些实现类?
这篇文章介绍了Java中Map接口的几种常用实现类:HashMap、LinkedHashMap、TreeMap和ConcurrentHashMap,以及它们适用的不同场景和线程安全性。
|
4月前
|
存储 算法 Java
滚雪球学Java(65):深入理解Java中的Map接口:实现原理剖析
【6月更文挑战第19天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
35 3
滚雪球学Java(65):深入理解Java中的Map接口:实现原理剖析
|
12月前
|
存储 Java
java集合框架------Map接口与实现类
java集合框架------Map接口与实现类
下一篇
无影云桌面